World editor: Триггер, активирующися при отсутствии игрока.
Нужен триггер (событие\условие), который активирует триггер, при отсутствии одного из игроков.

Лучший ответ:
Эмм нет события - игрок отсутствует, есть событие игрок вышел из игры, т.е сначала был но уже во время игры ливнул. Если вам нужно определить играет игрок или нет, делается это проверкой на состояние его слота - играет, является человеком \ ботом \ не используется.



Просмотров: 269

8gabriel8 #1 - 5 месяцев назад 0
Есть событие, что Игрок покинул игру. Оно требуется?
quq_CCCP #2 - 5 месяцев назад 1

Эмм нет события - игрок отсутствует, есть событие игрок вышел из игры, т.е сначала был но уже во время игры ливнул. Если вам нужно определить играет игрок или нет, делается это проверкой на состояние его слота - играет, является человеком \ ботом \ не используется.
Bergi_Bear #3 - 5 месяцев назад 0
А может под словом "отсутствие" подразумевается, что игрок неактивен, то есть афк?
Steal nerves #4 - 5 месяцев назад (отредактировано ) 0
Bergi_Bear, такое сложно отследить. Вернее невозможно отследить было ли у игрока действие. Мб надо отслеживать нажатие клавиш мыши и клавиатуры (а такое реально?).
Если нажатие клавиш реально отследить, тогда таймером можно отслеживать когда нажал последнюю клавишу. Если игрок последнюю клавишу нажал 1 минут назад, значит неактивен. Или как? Игрок живой не может больше 1 минуты ничего не делать, тем более просматривать карты.
Еще надо проверять смещение камеры или курсора мыши, игрок мб двигает мышкой камеру (при этом не нажимая ничего).
8gabriel8 #5 - 5 месяцев назад 0
Подозреваю, что автор поставил quq_CCCP + в репутацию, удовлетворившись его ответом
Steal nerves #6 - 5 месяцев назад 0
8gabriel8, мне просто интересно можно ли такой костыль на афк сделать или нет. Новые патчи вышли, мем хак есть.
8gabriel8 #7 - 5 месяцев назад 1
По идее принцип ты описал, дополню лишь, что ещё событие выделения стоит добавить.
nvc123 #8 - 5 месяцев назад 1
Steal nerves, ты в доту играл?
там есть команды -afk и -kickafk
-afk показывает как давно игроки афк
-kickafk позволяет кикнуть игрока который афк более 5 минут
Steal nerves #9 - 5 месяцев назад 0
» чат, комманды
function CB2 takes nothing returns nothing
local integer i=1
local player p
local integer x=0
if RC0 then
loop
exitwhen i>5
set p=BO[i]
if NYI(p)and((TimerGetElapsed(M))-L[GetPlayerId(p)])/60>0.2 then
set x=x+1
call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,U2,15.00,C0[GetPlayerId(p)]+(D30[GetPlayerId((p))])+&q​uot;|r"+" "+GetObjectName(1848653124)+" "+R2S(((TimerGetElapsed(M))-L[GetPlayerId(p)])/60)+" "+GetObjectName(1311782214))
endif
set p=CO[i]
if NYI(p)and((TimerGetElapsed(M))-L[GetPlayerId(p)])/60>0.2 then
set x=x+1
call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,U2,15.00,C0[GetPlayerId(p)]+(D30[GetPlayerId((p))])+&q​uot;|r"+" "+GetObjectName(1848653124)+" "+R2S(((TimerGetElapsed(M))-L[GetPlayerId(p)])/60)+" "+GetObjectName(1311782214))
endif
set i=i+1
endloop
if x<1 then
call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,U2,15.00,GetObjectName(1311782225))
else
call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,U2,15.00," ")
endif
endif
endfunction

function CC2 takes nothing returns nothing
local integer L9I=S2I(SubString(GetEventPlayerChatString(),9,StringLength(GetEventPlayerChatString())))
local integer i=1
local player p
local string F21
if RC0 then
if(Z0<10)then
set F21=I2S(H0)+":0"+I2S(Z0)
else
set F21=I2S(H0)+":"+I2S(Z0)
endif
if L9I<1 or RD0[L9I]==false then
loop
exitwhen i>5
set p=BO[i]
if NYI(p)and((TimerGetElapsed(M))-L[GetPlayerId(p)])>300.0 and RD0[GetPlayerId(p)]==false then
set RD0[GetPlayerId(p)]=true
call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,U2,15.00,C0[GetPlayerId(p)]+(D30[GetPlayerId((p))])+&q​uot;|r"+" "+GetObjectName(1848653127)+" "+R2S(((TimerGetElapsed(M))-L[GetPlayerId(p)])/60)+" "+GetObjectName(1311782214))
call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,U2,15.00,GetObjectName(1848653135)+" |cff99ccff-kickafk "+I2S(GetPlayerId(p))+" |r "+GetObjectName(1848653136))
call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,U2,15.00," ")
endif
set p=CO[i]
if NYI(p)and((TimerGetElapsed(M))-L[GetPlayerId(p)])>300.0 and RD0[GetPlayerId(p)]==false then
set RD0[GetPlayerId(p)]=true
call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,U2,15.00,C0[GetPlayerId(p)]+(D30[GetPlayerId((p))])+&q​uot;|r"+" "+GetObjectName(1848653127)+" "+R2S(((TimerGetElapsed(M))-L[GetPlayerId(p)])/60)+" "+GetObjectName(1311782214))
call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,U2,15.00,GetObjectName(1848653135)+" |cff99ccff-kickafk "+I2S(GetPlayerId(p))+" |r "+GetObjectName(1848653136))
call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,U2,15.00," ")
endif
set i=i+1
endloop
call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,U2,15.00," ")
elseif NYI(Player(L9I))==true and IsPlayerAlly(GetTriggerPlayer(),Player(L9I))==true then
call DisplayTimedTextToPlayer(Player(L9I),0,U2,3600,"|c00ff0303"+GetObjectName(1848653125)+&quo​t;|r")
call Z51(Player(L9I))
set K3[GetPlayerId(Player(L9I))]="|c00555555"+F21+"|r"
call RemovePlayer(Player(L9I),PLAYER_GAME_RESULT_DEFEAT)
call F32(Player(L9I))
if ZL then
call OS1(Player(L9I))
endif
set EA0[GetPlayerId(Player(L9I))]=true
call Z41(Player(L9I))
call PDI(P2,30.00,"|c00ff0303"+(D30[GetPlayerId((Player(L9I)))])+" "+GetObjectName(1848653125)+"|r")
endif
endif
endfunction

//нас интересует только call R9I("CB2",BI2) и call R9I("CC2",B12)
function AC2 takes nothing returns nothing
local string AD2=StringCase(GetEventPlayerChatString(),false)
local boolean N7O=AD2=="-random"or AD2=="-random int"or AD2=="-random agi"or AD2=="-random str"
local boolean AE2=AD2=="-repick"
local boolean AF2=AD2=="-gameinfo"
local boolean AG2=SubString(AD2,0,5)=="-swap"
local boolean AH2=AD2=="-recreate"
local boolean AZ2=AD2=="-unstuck"
local boolean AV2=AD2=="-matchup"or AD2=="-ma"
local boolean AW2=AD2=="-movespeed"or AD2=="-ms"
local boolean AX2=AD2=="-msa"
local boolean AY2=AD2=="-disablehelp"
local boolean AJ2=AD2=="-enablehelp"
local boolean AK2=AD2=="-creepstats"or AD2=="-cs"
local boolean AL2=AD2=="-cson"or AD2=="-csoff"
local boolean AM2=AD2=="-hidemsg"
local boolean AN2=AD2=="-showmsg"
local boolean AS2=AD2=="-weather snow"or AD2=="-weather rain"or AD2=="-weather off"or AD2=="-weather random"or AD2=="-weather wind"or AD2=="-weather moonlight"
local boolean AT2=AD2=="-showdeny"or AD2=="-hidedeny"
local boolean AR2=AD2=="-denyinfo"or AD2=="-di"
local boolean AP2=AD2=="-don"or AD2=="-deathon"or AD2=="-doff"or AD2=="-deathoff"
local boolean AQ2=SubString(AD2,0,5)=="-roll"and AD2!="-rollhero"
local boolean AU2=AD2=="-hhn"or AD2=="-hideheronames"
local boolean B02=AD2=="-mute"
local boolean BI2=AD2=="-afk"
local boolean B12=SubString(AD2,0,8)=="-kickafk"
local boolean BO2=AD2=="-apm"
local boolean B22=AD2=="-clear"
local boolean OWO=AD2=="-courier"
local boolean AH=AD2=="-ah"
local boolean B32=AD2=="-invokelist"or AD2=="-il"
local boolean B42=AD2=="-list"
local boolean B52=AD2=="-rolloff"
local boolean B62=AD2=="-rollon"
local boolean B72=SubString(AD2,0,6)=="-music"
local boolean B82=SubString(AD2,0,6)=="-water"
local boolean B92=SubString(AD2,0,6)=="-quote"
local boolean BA2=SubString(AD2,0,3)=="-cm"
local boolean BB2=SubString(AD2,0,9)=="-itemswap"
local boolean BC2=AD2=="-bonus"
local boolean BD2=AD2=="-rollhero"or AD2=="-rh"
local boolean BE2=SubString(AD2,0,9)=="-rickroll"
local boolean NoSwitch=AD2=="-noswitch"
local boolean BF2=SubString(AD2,0,7)=="-switch"or AD2=="-ok"or AD2=="-no"
local boolean Terrain=AD2=="-terrain"or AD2=="-terrain default"or AD2=="-terrain snow"
local boolean BG2=AD2=="-tips"
local boolean BH2=AD2=="-ii"or AD2=="-iteminfo"
local boolean BZ2=AD2=="-center"or AD2=="-centeroff"or AD2=="-c"or AD2=="-co"
local boolean BV2=AD2=="-unlock"
local boolean BW2=AD2=="-disableselection"or AD2=="-ds"
local boolean BX2=AD2=="-enableselection"or AD2=="-es"
local boolean BY2=AD2=="-sleep"
local boolean BJ2=AD2=="-calm"
local boolean SJI=AD2=="-st"
local boolean BK2=AD2=="-nosanta"
call R9I("BL2",N7O)
call R9I("BM2",AE2)
call R9I("BN2",AF2)
call R9I("BS2",AG2)
call R9I("BT2",AH2)
call R9I("BR2",AZ2)
call R9I("BP2",AV2)
call R9I("BQ2",AW2)
call R9I("BU2",AX2)
call R9I("C02",AY2)
call R9I("CI2",AJ2)
call R9I("C12",AK2)
call R9I("CO2",AL2)
call R9I("C22",AM2)
call R9I("C32",AN2)
call R9I("C42",AS2)
call R9I("C52",AT2)
call R9I("C62",AR2)
call R9I("C72",AP2)
call R9I("C82",AQ2)
call R9I("C92",AU2)
call R9I("CA2",B02)
call R9I("CB2",BI2)
call R9I("CC2",B12)
call R9I("CD2",BO2)
call R9I("CE2",B22)
call R9I("CF2",OWO)
call R9I("CG2",AH)
call R9I("CH2",B32)
call R9I("CZ2",B42)
call R9I("CV2",B52)
call R9I("CW2",B62)
call R9I("CX2",B72)
call R9I("CY2",B82)
call R9I("CJ2",B92)
call R9I("CK2",BA2)
call R9I("CL2",BB2)
call R9I("CM2",BC2)
call R9I("CN2",BD2)
call R9I("CS2",BE2)
call R9I("CT2",BF2)
call R9I("CR2",BH2)
call R9I("CP2",BG2)
call R9I("CQ2",BZ2)
call R9I("CU2",BV2)
call R9I("D02",BW2)
call R9I("DI2",BX2)
call R9I("D12",BY2)
call R9I("DO2",SJI)
call R9I("D22",BJ2)
call R9I("D32",BK2)
endfunction
» каждые 5 сек проверяет игроков на афк, и выводит сообщение что можно кикнуть
function F62 takes nothing returns boolean
local integer i=1
local player p
local real F21=(TimerGetElapsed(M))
if RC0 then
loop
exitwhen i>5
set p=BO[i]
if NYI(p)and(F21-L[GetPlayerId(p)])>300.0 and RD0[GetPlayerId(p)]==false then
set RD0[GetPlayerId(p)]=true
call PDI(OO,15,C0[GetPlayerId(p)]+(D30[GetPlayerId((p))])+"|r"+" "+GetObjectName(1848653127)+" "+R2S((F21-L[GetPlayerId(p)])/60)+" "+GetObjectName(1311782214))
call PDI(OO,15,GetObjectName(1848653135)+" |cff99ccff-kickafk "+I2S(GetPlayerId(p))+" |r "+GetObjectName(1848653136))
call PDI(OO,15," ")
endif
set p=CO[i]
if NYI(p)and(F21-L[GetPlayerId(p)])>300.0 and RD0[GetPlayerId(p)]==false then
set RD0[GetPlayerId(p)]=true
call PDI(AO,15,C0[GetPlayerId(p)]+(D30[GetPlayerId((p))])+"|r"+" "+GetObjectName(1848653127)+" "+R2S((F21-L[GetPlayerId(p)])/60)+" "+GetObjectName(1311782214))
call PDI(AO,15,GetObjectName(1848653135)+" |cff99ccff-kickafk "+I2S(GetPlayerId(p))+" |r "+GetObjectName(1848653136))
call PDI(AO,15," ")
endif
set i=i+1
endloop
endif
return false
endfunction
» ловит приказы. Короче когда отдал последний приказ
function R6I takes unit R7I returns nothing
call PauseUnit(R7I,true)
call IssueImmediateOrder(R7I,"stop")
call PauseUnit(R7I,false)
endfunction
function R1I takes player ROI,string LNI returns nothing
local sound R3I=CreateSoundFromLabel("InterfaceError",false,false,false,10,10)
if(GetLocalPlayer()==ROI)then
if(LNI!="")and(LNI!=null)then
call ClearTextMessages()
call DisplayTimedTextToPlayer(ROI,0.50,-1.00,2.00,"|cffffcc00"+LNI+"|r")
endif
call StartSound(R3I)
endif
call KillSoundWhenDone(R3I)
endfunction

//ловим приказы (срабатываеи при событиях: юнит отдал приказ/отдал в цель/отдал в точку)
function F72 takes nothing returns boolean

//проверка: что юнит принадлежит только первой команде BO (1-5), или второй CO (1-5). Какая-то важная и непонятная проверка в доте.
if GetOwningPlayer(GetTriggerUnit())!=BO[0]and GetOwningPlayer(GetTriggerUnit())!=CO[0]then

	//счетчик приказов K, неизвестный параметр
	set K[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]=K[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]+​1
	
	//если эта не приказ атаки, ....
	if GetIssuedOrderId()!=851983 then //attack=851983
		set L[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]=(TimerGetElapsed(M))
		set RD0[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]=false
	endif
	
	//вроде эта проверка на то, что нельзя подбирать или атаковать чужой предмет, который лежит на земле
	if(GetIssuedOrderId()==851983 or GetIssuedOrderId()==851971)and GetOrderTargetItem()!=null then //attack=851983, smart = 851971
		

		if GetIssuedOrderId()==851983 or(GetIssuedOrderId()==851971 and(LoadBoolean(XY,(GetHandleId(GetItemPlayer(GetOrderTargetItem()))),(139)))==true)then
			if GetItemPlayer(GetOrderTargetItem())!=GetOwningPlayer(GetTriggerUnit())and IsPointInRegion(SK,GetItemX(GetOrderTargetItem()),GetItemY(GetOrderTargetItem()))==true then
				call DisableTrigger(GetTriggeringTrigger())
				call R6I(GetTriggerUnit())
				call R1I(GetOwningPlayer(GetTriggerUnit()),GetObjectName(1848657719)) //выводит сообщение что нельзя атаковать или подбирать
				call EnableTrigger(GetTriggeringTrigger())
			endif
		endif
	endif
endif
return false
endfunction
» функция main, инициирует триггеры
function main takes nothing returns nothing
local trigger t

//массив игроков. BO - первая команда, CO - вторая команда
set BO[0]=Player(0)
set BO[1]=Player(1)
set BO[2]=Player(2)
set BO[3]=Player(3)
set BO[4]=Player(4)
set BO[5]=Player(5)
set CO[0]=Player(6)
set CO[1]=Player(7)
set CO[2]=Player(8)
set CO[3]=Player(9)
set CO[4]=Player(10)
set CO[5]=Player(11)

//проверяет приказы игроков (в афк ли он или нет): если игрок отдал приказ, значит в игре
//еще проверяет и запрещает атаковать и подбирать чужие предметы
set t=CreateTrigger()
call QBI(t,EVENT_PLAYER_UNIT_ISSUED_ORDER) //регистр приказа без цели
call QBI(t,EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER) //регистр приказа в цель
call QBI(t,EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER) //регистр приказа в точку
call TriggerAddCondition(t,Condition(function F72))

//каждые 5 сек запускает. Проверяет каждого игрока, и сколько времени прошло с последнего действия
//Если прошло больше 300 сек (это 5 мин), значит игрока можно кикнуть (выгнать)
//сам триггер не кикает игрока, просто выводит сообщение игрокам, что его можно кикнуть
set t=CreateTrigger()
call TriggerRegisterTimerEvent(t,5,true)
call TriggerAddCondition(t,Condition(function F62))

//массив булеан. хранит информацию, эта штука дает инфу, что ушел ли игрок в афк на 5 мин.
//так понимаю эта логическая говорит, что показал сообщение. чтоб повторно его не показывать в функции F62
set RD0[GetPlayerId(BO[1])]=false
set RD0[GetPlayerId(BO[2])]=false
set RD0[GetPlayerId(BO[3])]=false
set RD0[GetPlayerId(BO[4])]=false
set RD0[GetPlayerId(BO[5])]=false
set RD0[GetPlayerId(CO[1])]=false
set RD0[GetPlayerId(CO[2])]=false
set RD0[GetPlayerId(CO[3])]=false
set RD0[GetPlayerId(CO[4])]=false
set RD0[GetPlayerId(CO[5])]=false
set t=null

//чат, включает настройки (команды) в доте. в том числе на -afk, -kickafk
set t=CreateTrigger()
call TriggerRegisterPlayerChatEvent(t,BO[1],"-",false)
call TriggerRegisterPlayerChatEvent(t,BO[2],"-",false)
call TriggerRegisterPlayerChatEvent(t,BO[3],"-",false)
call TriggerRegisterPlayerChatEvent(t,BO[4],"-",false)
call TriggerRegisterPlayerChatEvent(t,BO[5],"-",false)
call TriggerRegisterPlayerChatEvent(t,CO[1],"-",false)
call TriggerRegisterPlayerChatEvent(t,CO[2],"-",false)
call TriggerRegisterPlayerChatEvent(t,CO[3],"-",false)
call TriggerRegisterPlayerChatEvent(t,CO[4],"-",false)
call TriggerRegisterPlayerChatEvent(t,CO[5],"-",false)
call TriggerAddAction(t,function AC2)

//запускает таймер с начала игры, это связано с афк. все игроки в массив L сохраняют последнее действие
//потом сравнивают текущее время таймера M c временем L, короче проверяют сколько прошло.
//К примеру если прошло 60 сек, значит игрок не активен
set M=CreateTimer()
call TimerStart(M,99999.00,false,null)
endfunction