Перейти к содержанию

Скриптеры помогите плз


Рекомендуемые сообщения

написал скрипт (код ниже) для своего плагина, повесил на стандартные костры и добавил им функцию "Can carry" по результатам первого же теста (красным выделил баги, зелёным то что работает как я и хотел):

поднялся на маяк в Сейда нин, наложился эффект Firepit_good_spell, залез в огонь снялся эффект Firepit_good_spell, но не появился Firepit_bad_spell, зато появился непропадающий месаджбокс "Вы горите!!!", далее подобрал оба костра, месаджбокс НЕ пропал, вокруг чара появился эффект от удара огнём (как должно быть при Firepit_bad_spell), но сами повреждения не наносились, выложил один из костров на землю эффекты пропали, повреждения не наносяться, эффект Firepit_good_spell НЕ появился, отошёл от выложеного костра на расстояние >512 изменений не последовало, подошёл обратно ничего не произошло, выложил второй костёр появился эффект Firepit_good_spell наступил на него, Firepit_good_spell пропал появился месаджбокс но эффект Firepit_bad_spell не появился. Поднял один из костров обратно, эффект Firepit_bad_spell убил игрока быстрее чем надо.

пояснение:

Firepit_bad_spell (характеристика) наносит урон огнём 1п и ставит уязвимость огню от 1 до 2п

Firepit_good_spell (характеристика) восстанавливает 2п усталости, 1п манны и 1п здоровья

 

чего я собстно хотел:

подходишь к костру на 512 получаешь Firepit_good_spell

наступил на огонь Firepit_good_spell пропадает появляетьсяFirepit_bad_spell

отошёл дальше чем на 512 все эффекты пропали (только если нет рядом другого костра)

когда костёр в рюкзаке, эффекты не действуют

чего я собстно сделал:

begin Firepit_sc
if ( GetDistance, Player < 512 )	[color="#FF00FF"];если до огня ближе чем 512[/color]
if ( GetDistance, Player < 10 )	[color="#FF00FF"];но если ближе 10[/color]
	Player -> AddSpell "Firepit_bad_spell"	[color="#FF00FF"];игрок горит[/color]
	MessageBox "Вы горите!!!"
	if ( Player -> GetSpellEffects, "Firepit_good_spell" == 1 )
		Player -> RemoveSpell "Firepit_good_spell"	[color="#FF00FF"];причём хороший эффект от костра не действует[/color]
	endif
else				[color="#FF00FF"];но если дальше 10[/color]
	Player -> AddSpell "Firepit_good_spell"		[color="#FF00FF"];действует хороший эффект костра (как в WoW:)[/color]
	if ( Player -> GetSpellEffects, "Firepit_bad_spell"== 1 )
		Player -> RemoveSpell "Firepit_bad_spell" [color="#FF00FF"];и перестаёт действовать эффект ожога[/color]
	endif
endif
else					[color="#FF00FF"];однако если мы дальше чем 512 от костра[/color]
if ( Player -> GetSpellEffects, "Firepit_bad_spell"== 1 )	[color="#FF00FF"];и получаем ожёг[/color]
	Player -> RemoveSpell "Firepit_bad_spell"		[color="#FF00FF"];то мы его не получаем (кажись тут возникает конфликт от второго костра)[/color]
endif
if ( Player -> GetSpellEffects, "Firepit_good_spell" == 1 )	[color="#FF00FF"];и если мы имеем хороший эффект[/color]
	Player -> RemoveSpell "Firepit_good_spell"		[color="#FF00FF"];он тоже пропадает, мы же ушли далеко от костра... (но похоже и тут будет конфликт с другими кострами, если они ближе 512)[/color]
endif
endif
end Firepit_sc

 

ну вот собстно конфликтный момент вроде нашёл но как его профиксить не знаю, подскажите плиз.

удалить последнй блок (который снимает эффекты) нельзя так как игрок после встречи с костром не потеряет эффект уже никогда.

Изменено пользователем Dyx
Ссылка на комментарий
Поделиться на другие сайты

Чтоб небыло конфликтов от нескольких костров нужна глобальная переменная и скрит ее обрабатывающий.

На кострах локальные скрипты будут прибавлять/отнимать этой переменной свое действие (нагрев).

Небольшое значение - тепло, а чем больше - тем хуже (от двух сгоришь быстрей).

 

Скрипт написан совсем не в какие ворота, без всяких фиксаций событий...

 

if ( GetDistance, Player

Player -> AddSpell "Firepit_bad_spell" ;игрок горит

MessageBox "Вы горите!!!"

 

Вот сколько на компе есть фпс - столько раз в секунду и будет лупить это сообщение, пока ты там.

И проверки на поднятие костра тоже нет... ну и счего должны эффекты исчезать ?

 

Так что скипт надо не править, а писать совсем другой. Только я пас... нет времени.

Ссылка на комментарий
Поделиться на другие сайты

Для решение этой задачи надо следующее:

  1. Создаем спеллы типа "Характеристика" с ID Firepit_good_spell и Firepit_bad_spell и даем им нужные эффекты
  2. Создать активатор (хотя можно и miscitem) с ID firepit_world (это будет костер, который будет добавлять/удалять эффекты) и повесить на него такой скрипт:
    [color="blue"]Begin[/color] EW4_Dyx_firepits_world_scpt
    [color="blue"]short[/color] state [color="grey"]; 0 - далеко, 1 - близко, 2 - горит[/color]
    [color="blue"]float[/color] distance [color="grey"];расстояние до игрока[/color]
    
    [color="blue"]if[/color] [color="green"]([/color] [color="orange"]MenuMode[/color] [color="green"]==[/color] [color="red"]1[/color] [color="green"])[/color]
    	[color="blue"]return[/color]
    [color="blue"]endif[/color]
    
    [color="blue"]if[/color] [color="green"]([/color] [color="brown"]GetDisabled[/color] [color="green"]==[/color] [color="red"]1[/color] [color="green"])[/color] [color="grey"];если мы отключены[/color]
    	[color="blue"]SetDelete[/color] [color="red"]1[/color] [color="grey"];удалимся[/color]
    	[color="blue"]return[/color]
    [color="blue"]endif[/color]
    
    [color="blue"]if[/color] [color="green"]([/color] [color="orange"]OnActivate[/color] [color="green"]==[/color] [color="red"]1[/color] [color="green"])[/color] [color="grey"];Если игрок нас активировал[/color]
    	[color="brown"]disable[/color] [color="grey"];отключимся[/color]
    	[color="orange"]Player[/color][color="green"]->[/color][color="brown"]RemoveSpell[/color] [color="magenta"]"Firepit_good_spell"[/color] [color="grey"];уберем хороший эффект[/color]
    	[color="orange"]Player[/color][color="green"]->[/color][color="brown"]RemoveSpell[/color] [color="magenta"]"Firepit_bad_spell"[/color] [color="grey"];и плохой тоже[/color]
    	[color="orange"]Player[/color][color="green"]->[/color][color="brown"]AddItem[/color] [color="magenta"]"firepit_inventory"[/color] [color="red"]1[/color] [color="grey"]; добавим переносной костер в инвентарь[/color]
    	[color="blue"]return[/color] 
    [color="blue"]endif[/color]
    
    [color="blue"]set[/color] state [color="blue"]to[/color] [color="red"]2[/color] [color="green"]*[/color] [color="green"]([/color] [color="orange"]Player[/color][color="green"]->[/color][color="brown"]GetSpellEffects[/color] [color="magenta"]"Firepit_bad_spell"[/color] [color="green"])[/color] [color="grey"];установка статуса[/color]
    [color="blue"]set[/color] state [color="blue"]to[/color] state [color="green"]+[/color] [color="orange"]Player[/color][color="green"]->[/color][color="brown"]GetSpellEffects[/color] [color="magenta"]"Firepit_good_spell"[/color][color="grey"];установка статуса, часть 2[/color]
    [color="blue"]set[/color] distance [color="blue"]to[/color] [color="brown"]GetDistance[/color] [color="orange"]Player[/color] [color="grey"];узнаем расстояние[/color]
    
    [color="blue"]if[/color] [color="green"]([/color] distance [color="green"]<=[/color] [color="red"]32[/color] [color="green"])[/color] [color="grey"];Если слишком близко[/color]
    	[color="blue"]if[/color] [color="green"]([/color] state [color="green"]!=[/color] [color="red"]2[/color] [color="green"])[/color] [color="grey"];И мы еще не в этом состоянии[/color]
    		[color="brown"]MessageBox[/color] [color="magenta"]"Вы горите!"[/color] [color="grey"];сообщим игроку[/color]
    		[color="orange"]Player[/color][color="green"]->[/color][color="brown"]AddSpell[/color] [color="magenta"]"Firepit_bad_spell"[/color] [color="grey"];добавим плохой эффект[/color]
    		[color="orange"]Player[/color][color="green"]->[/color][color="brown"]RemoveSpell[/color] [color="magenta"]"Firepit_good_spell"[/color] [color="grey"];и заберем хороший[/color]
    	[color="blue"]endif[/color]
    [color="blue"]elseif[/color] [color="green"]([/color] distance [color="green"]<=[/color] [color="red"]256[/color] [color="green"])[/color] [color="grey"];если мы все же на оптимальном расстоянии[/color]
    	[color="blue"]if[/color] [color="green"]([/color] state [color="green"]!=[/color] [color="red"]1[/color] [color="green"])[/color] [color="grey"];И мы еще не в этом состоянии[/color]
    		[color="brown"]MessageBox[/color] [color="magenta"]"Вы чувствуете живительное тепло костра..."[/color] [color="grey"];сообщим игроку[/color]
    		[color="orange"]Player[/color][color="green"]->[/color][color="brown"]AddSpell[/color] [color="magenta"]"Firepit_good_spell"[/color] [color="grey"];добавим хороший эффект[/color]
    		[color="orange"]Player[/color][color="green"]->[/color][color="brown"]RemoveSpell[/color] [color="magenta"]"Firepit_bad_spell"[/color] [color="grey"];и уберем плохой[/color]
    	[color="blue"]endif[/color]
    [color="blue"]else[/color] [color="grey"];ежели игрок еще дальше[/color]
    	[color="blue"]if[/color] [color="green"]([/color] state [color="green"]!=[/color] [color="red"]0[/color] [color="green"])[/color] [color="grey"];если мы слишком далеко[/color]
    		[color="orange"]Player[/color][color="green"]->[/color][color="brown"]RemoveSpell[/color] [color="magenta"]"Firepit_good_spell"[/color] [color="grey"];уберем хороший эффект[/color]
    		[color="orange"]Player[/color][color="green"]->[/color][color="brown"]RemoveSpell[/color] [color="magenta"]"Firepit_bad_spell"[/color] [color="grey"];и плохой тоже[/color]
    	[color="blue"]endif[/color]
    [color="blue"]endif[/color]
    [color="blue"]End[/color]
    


  3. Создать miscitem с ID firepit_inventory - это будет костер в инвентаре (при выбрасывании он будет на своем месте снова ставить активатор) и вешаем на него такой скрипт:
    [color="blue"]Begin[/color] EW4_Dyx_firepits_inventory_scpt
    [color="blue"]Short[/color] [color="orange"]OnPCDrop[/color] [color="grey"];Устанавливается в 1 когда игрок выбрасывает эту вещь[/color]
    
    [color="blue"]if[/color] [color="green"]([/color] [color="orange"]MenuMode[/color] [color="green"]==[/color] [color="red"]1[/color] [color="green"])[/color]
    	[color="blue"]return[/color]
    [color="blue"]endif[/color]
    
    [color="blue"]if[/color] [color="green"]([/color] [color="brown"]GetDisabled[/color] [color="green"]==[/color] [color="red"]1[/color] [color="green"])[/color] [color="grey"];если мы отключены[/color]
    	[color="blue"]SetDelete[/color] [color="red"]1[/color] [color="grey"];удалимся[/color]
    	[color="blue"]return[/color]
    [color="blue"]endif[/color]
    
    [color="blue"]If[/color] [color="green"]([/color] [color="orange"]OnPCDrop[/color] [color="green"]==[/color] [color="red"]1[/color] [color="green"])[/color] [color="grey"];если нас выбросили[/color]
    	[color="brown"]disable[/color] [color="grey"];отключимся[/color]
    	[color="brown"]PlaceAtMe[/color] [color="magenta"]"firepit_world"[/color] [color="red"]1[/color] [color="red"]0[/color] [color="red"]0[/color] [color="grey"];и поставим на своем месте костер стационарный[/color]
    [color="blue"]endif[/color]
    
    [color="blue"]End[/color]
    


  4. Расстояния я подкорректировал - расстояние в 10 единиц игрок может и не достичь из-за роста, 32 - в самый раз, ну а 512 - далекова-то для костра, впрочем можешь вернуть свои значения :-)
  5. В принципе всё. Только по-хорошему надо все ID переименовать на что-то более уникальное во избежание конфликтов. Но с этим уже, надеюсь, и сам справишься.

 

Кстати, тема не в том разделе. Кто тут с правами, перенесите её, пожалуйста, в скрипторий.

Изменено пользователем Эндер Виггин
Ссылка на комментарий
Поделиться на другие сайты

Спасибо всем кто откликнулся

...

if ( GetDisabled == 1 )

SetDelete 1

...

хм... на сколько помниться удаление объекта из скрипта на этом же объекте ведёт к крашу игры :dontknow:

если это не так, то поправте меня - я тогда так и сделаю, но просто я не люблю делать объекты которые при выкладывании заменяються активаторами. они потом в дисэйбле остаються лежать и сейв засоряют=(

 

может EW4_Dyx_firepits_world_scpt доработать так чтобы работал с самого костра?

 

расстояние в 10 единиц игрок может и не достичь из-за роста, 32 - в самый раз, ну а 512 - далекова-то для костра

 

ну на счёт 10 это я уже проверил, действительно мало, а число 512 брал из радиуса освещения (т.е. костёр "греет" на расстоянии своего освещения)

 

как альтернатива, может попробовать что-то вроде этого?

Begin EW4_Dyx_firepits_scrpt_v2.0

short state ; 0 - далеко, 1 - близко, 2 - горит

;этот блок позволяет подбирать костёр через меню инвентаря и при этом убрать эффекты
if ( MenuMode == 1 )
if ( OnActivate == 1 )
	Player->RemoveSpell "Firepit_good_spell"
	Player->RemoveSpell "Firepit_bad_spell"
	Activate
endif
return
endif

;установка статуса
set state to 2 * ( Player->GetSpellEffects "Firepit_bad_spell" )
set state to state + Player->GetSpellEffects "Firepit_good_spell"

if ( GetDistance, Player <= 32 ) ;Если слишком близко
if ( state != 2 ) ;И мы еще не в этом состоянии
	MessageBox "Вы горите!" ;сообщим игроку
	Player->AddSpell "Firepit_bad_spell" ;добавим плохой эффект
	Player->RemoveSpell "Firepit_good_spell" ;и заберем хороший
endif
elseif ( GetDistance, Player <= 300 ) ;если мы все же на оптимальном расстоянии
if ( state != 1 ) ;И мы еще не в этом состоянии
	MessageBox "Вы чувствуете живительное тепло костра..." ;сообщим игроку
	Player->AddSpell "Firepit_good_spell" ;добавим хороший эффект
	Player->RemoveSpell "Firepit_bad_spell" ;и уберем плохой
endif
else ;ежели игрок еще дальше
if ( state != 0 ) ;если мы слишком далеко
	Player->RemoveSpell "Firepit_good_spell" ;уберем хороший эффект
	Player->RemoveSpell "Firepit_bad_spell" ;и плохой тоже
endif
endif
End

 

так же думаю в начале скрипта вставить блок типа такого:

short timer
short done
if ( done == 0)
set timer to GetSecondsPassed
set done to 1
else
if ( timer <= 5 )
	return
else
	set timer to 0
	set done to 0
endif
endif

таким образом скрипт будет прокручиваться не каждый фрэйм а раз в 5 секунд что разгрузит проц и создаст "постэффект" т.е. после вылезания из огня игрок будет гореть ещё около 5 сек и после удаления эффект будет исчезать не сразу.

 

или может вообще сделать так:

при расстоянии меньше 32 костёр кастует (вообщем использовать команду cast вместо addspell) "плохой" эффект типа "заклинание" длительностью 5 секунд, при расстоянии от 32 до 300 "хороший" эффект длительностью 5 секунд, и при расстоянии больше 300 ничего не происходит. и прокручивать скрипт раз в 5 секунд. плюс такого способа в том что можно менять продолжительность эффектов и делать их разными не изменяя скрипт, минус в том что раз в 5 секунд в игрока будет прилетать заклинание, что несколько портит реалистичность всей картины.

 

посоветуйте какой вариант будет лучше? особенно в плане производительности.

 

Добавлено:

проверил EW4_Dyx_firepits_scrpt_v2.0 всё работает как надо кроме одного, при подборе костров вокруг игрока появляеться эффект "урон огня" но повреждения не наносяться (возможно потому что подключен плагин dynamic regeneration)

то есть получаеться когда какой либо предмет находится у игрока в инвенторе игра считает что его расстояние до игрока равно 0...

Добавлено:

добавил проверку на расстояние = 0 получилось что если у чара в рюкзаке есть костёр остальные костры не действуют никак на него=(

похоже и вправду без деления объектов на "объект для мира" и "объект для инвенторя" не обойтись(

попробую вариант с cast'ом, если не получиться - я в отчаиньи, придёться делать через 2 объекта=(

Изменено пользователем Dyx
Ссылка на комментарий
Поделиться на другие сайты

хм... на сколько помниться удаление объекта из скрипта на этом же объекте ведёт к крашу игры

Как раз наоборот. Только с локального скрипта на объекте его можно удалять.

При этом сначала за десейблить и в следущем фрейме удалять.

А в сейв удаленные объекты не попадут.

 

Замену одних вещей на другие я тоже не люблю,

так как PlaceAtMe вроде требует триб...

 

Скрипты уже почти рабочие, но конфликт двух костров можно убрать только глобальным скриптом.

И еще очень важно заменить характеристику на обычный эффект иначе получишь геморой от телепорта

из дверей и прочего (спел не исчезнет).

 

А эффект в секунду сам пройдет.

Ссылка на комментарий
Поделиться на другие сайты

Тему перенес. В следующий раз внимательнее.

сорри :-[

 

заменил скрипт на вот такой:

begin Firepit_sc

float timer
short done

if ( MenuMode == 1 )
return
endif

[color="gray"];этот блок не даёт скрипту работать чаще чем раз в 5 секунд, теоретически;)[/color]
if ( done == 0)							[color="gray"];если таймер не отсчитывает 5[/color]
set timer to timer + GetSecondsPassed			[color="gray"];то пусть считает[/color]
set done to 1						[color="gray"];теперь считает[/color]
else								[color="gray"];если уже считает[/color]
if ( timer <= 5 )					[color="gray"];и насчитал пока меньше 5сек[/color]
	MessageBox "Debug: timer is %f", timer		[color="gray"];покажем скока же он насчитал[/color]
else							[color="gray"];а если насчитал больше 5сек[/color]
	MessageBox "Debug: timer is OK now"		[color="gray"];пусть напишет нам смску[/color]
	set timer to 0					[color="gray"];и снова начнёт считать с 0[/color]
endif
endif
[color="gray"];---------------------------------------------------------------[/color]
if ( GetDistance, Player == 0 ) 				[color="gray"];если вы в самом эпицентре или костёр у вас в рюкзаке[/color]
return
elseif ( GetDistance, Player <= 32 )				[color="gray"];Если слишком близко[/color]
MessageBox "Вы горите!"					[color="gray"];сообщим игроку[/color]
Cast, Firepit_bad_spell, Player				[color="gray"];добавим плохой эффект[/color]
elseif ( GetDistance, Player <= 300 )				[color="gray"];если мы все же на оптимальном расстоянии[/color]
MessageBox "Вы чувствуете живительное тепло костра..."		[color="gray"];сообщим игроку[/color]
Cast, Firepit_good_spell, Player			[color="gray"];добавим хороший эффект[/color]
else
return
endif
End

в итоге дебагер показывает число от 0.028 до 0.035 зависящее от фпс а костёр при приближении кастует спелл в каждом фрэйме=((

как таймер построить? нифига не понимаю %(

 

з.ы. соответственно поменял Firepit_good_spell и Firepit_bad_spell с "характеристики" на "заклинание" "касание" радиус 0 (на чара применяеться всё норм, если бы тока не в каждом фрэйме :-( )

 

пробовал ставить ретёрны вот так:

...
set timer to timer + GetSecondsPassed
set done to 1
[color="#FF0000"]return[/color]
else
if ( timer <= 5 )
	[color="#FF0000"]return[/color]
	MessageBox "Debug: timer is %f", timer
else
...

тогда вообще ничего не происходит так как величина timer не становиться больше 5 :-( то и основной скрипт не выполняеться

Изменено пользователем Dyx
Ссылка на комментарий
Поделиться на другие сайты

Разумеется, он кастует в каждом фрейме. Нигде ж не сказано, что надо ретерниться. А в версии с ретурнами он у тебя выходит при начале отсчета таймером. Я, конечно, в этом слабо разбираюсь, но по здравому смыслу и если без глобальных скриптов, то надо так:

begin Firepit_sc

float timer
short casted;если спелл уже применен

if ( MenuMode == 1 )
return
endif

;этот блок не даёт скрипту работать чаще чем раз в 5 секунд, теоретически;)
if ( timer <= 5 ); насчитал пока меньше 5сек
set timer to timer + GetSecondsPassed; пусть считает, а то он считал только если не считает, вот такой бред.
MessageBox "Debug: timer is %f", timer;покажем скока же он насчитал
else;а если насчитал больше 5сек
MessageBox "Debug: timer is OK now";пусть напишет нам смску
set timer to 0;и снова начнёт считать с 0
set casted to 0;начинаем каст заново
endif
;---------------------------------------------------------------
if(casted == 1); если кастанули, выходим.
return
endif
if ( GetDistance, Player == 0 );если вы в самом эпицентре или костёр у вас в рюкзаке
return
elseif ( GetDistance, Player <= 32 );Если слишком близко
MessageBox "Вы горите!";сообщим игроку
Cast, Firepit_bad_spell, Player;добавим плохой эффект
set casted to 1;кастанули
elseif ( GetDistance, Player <= 300 );если мы все же на оптимальном расстоянии
MessageBox "Вы чувствуете живительное тепло костра...";сообщим игроку
Cast, Firepit_good_spell, Player;добавим хороший эффект
set casted to 1;кастанули
else
return
endif
End

 

Я думаю, так надо. Но ничего не гарантируется!

Ссылка на комментарий
Поделиться на другие сайты

Не понятно почему не хочешь сделать глобальный скрипт.

 

При локальных нельзя пользоваться постоянными проклятиями и хар-ками.

И куча прочих проблем... Может просто не понял принципа его работы?

 

На всякий случай поясню.

 

Локальные скрипты в зависимости от растояния 1 в сек прибавляют глобальной переменной количество тепла, и запускают глобальный скрипт (если не запущен).

 

При этом все костры получатся независимы (у них может быть разная величина жара и дистанция) и их эффект будет складываться.

 

Глобальный 1 в сек уменьшает эту переменную до нуля и цепляет игроку спел в зависимости от полученной величины (тепло, жар10, жар20... огонь), и при обнулении останавливается.

Ссылка на комментарий
Поделиться на другие сайты

Я думаю, так надо. Но ничего не гарантируется!

РАБОТАЕТ! :yahoo: :bravo: :dance: Спасибо :thumbup:

единственный глюк в том что при кастовании хорошего эффекта "зависает" звук тоесть костёр кастует раз в 5 секунд а звук каста идёт постоянно, это видимо уже движок тупит(( а ещё бесит противное колечко которое появляеться вокруг костра когда срабатывает каст. (такое же возникает вокруг святилищ, когда подаяния делаешь) ну и разумееться вокруг чара летают всякие сияющие огоньки... это увы неприятно, и совсем нарушает восприятие... я даже не знаю как это убрать, если только текстуры все заменить на прозрачные и звуки отключить у спеллов...

 

Не понятно почему не хочешь сделать глобальный скрипт.

 

При локальных нельзя пользоваться постоянными проклятиями и хар-ками.

И куча прочих проблем... Может просто не понял принципа его работы?

я понял принцип но не совсем разбираюсь в глобальных скриптах.. а если точнее я их никогда не писал и не вникал.

если не сложно можешь написать эти скрипты? для костра и глобальный?

 

 

з.ы. в том же плагине прописал скрипт на подушки:

begin pillow_sc
short done1
short done2

if ( GetPCSleep == 1 )	[color="grey"];если спим[/color]
if ( GetDistance, Player <= 256 )	[color="grey"];ближе чем на 256 от подушки[/color]
	Player -> AddSpell "pillow_sleep_spell"	[color="grey"];получаем эффект[/color]
	if ( done1 == 0 )	[color="grey"];о чём ставим в известность игрока[/color]
		MessageBox "Вы спите на мягкой подушке, отчего ваш сон много приятнее и вы быстрее высыпаетесь."
		set done1 to 1	[color="grey"];это чтоб масага не вылезала ещефрейменно:)[/color]
		return
	endif
endif
else	[color="grey"];если НЕ спим[/color]
if ( GetDistance, Player <= 16 )	[color="grey"];но находимся на подушке[/color]
	Player -> AddSpell "pillow_seet_spell"	[color="grey"];то получаем эффект[/color]
	if ( done2 == 0 )	[color="grey"];о чём ставим в известность игрока[/color]
		MessageBox "Вы присели на подушку отчего ваша осталость проходит намного быстрее."
		set done2 to 1
		return
	endif
else	[color="grey"];но если мы не спим и не находимся на подушке[/color]
	if ( Player -> GetSpellEffects, "pillow_seet_spell" == 1 )	[color="grey"];и на нас действует эффект [/color][color="red"](а тут будет конфликт с соседней подушкой, если на неё сесть)[/color]
		Player -> RemoveSpell "pillow_seet_spell"	[color="grey"];мы его убираем[/color]
		set done2 to 0	[color="grey"];и делаем так чтобы масага вылезла в следующий раз когда эффект включиться[/color]
		return
	endif
endif
if ( Player -> GetSpellEffects, "pillow_sleep_spell" == 1 )
	Player -> RemoveSpell "pillow_sleep_spell"	[color="grey"];аналогично избавляемся от второго эффекта[/color]
	set done1 to 0	[color="grey"];и перезаряжаем вторую масагу[/color]
	return
endif
endif
end pillow_sc

Где накладываемые эффекты являються характеристиками. теперь вот думаю как го улучшить дабы небыло конфликта и не в каждом фрэйме addspell был :scratch:

Изменено пользователем Dyx
Ссылка на комментарий
Поделиться на другие сайты

По идее, глобальный скрипт - то же самое, что и обычный, только работает вне зависимости от предмета. Ну, попробую что-нибудь написать... (кстати, до этого я скриптов вообще не писал :-) )

 

begin Firepit_local_sc

float timer
short done
short warmhere

if ( MenuMode == 1 )
return
endif

;этот блок не даёт скрипту работать чаще чем раз в 2 секунды, теоретически;)
if ( timer <= 2 ); насчитал пока меньше 5сек
set timer to timer + GetSecondsPassed; пусть считает, а то он считал только если не считает, вот такой бред.
MessageBox "Debug: timer is %f", timer;покажем скока же он насчитал
else;а если насчитал больше 2сек
MessageBox "Debug: timer is OK now";пусть напишет нам смску
set timer to 0;и снова начнёт считать с 0
set done to 0
set warmhere to 0
endif
;---------------------------------------------------------------
if(done = 1);
return
endif
if ( GetDistance, Player == 0 );если вы в самом эпицентре или костёр у вас в рюкзаке
return
elseif ( GetDistance, Player <= 32 );Если слишком близко
set warmhere to 3
set done to 1
elseif ( GetDistance, Player <= 150 );если расстояние среднее
set warmhere to 2
set done to 1
elseif ( GetDistance, Player <= 300 );если мы все же на оптимальном расстоянии
set warmhere to 1
set done to 1
endif
set globalwarm to globalwarm + warmhere
End

 

begin Firepit_global_sc;глобальный скрипт

float timergl
short casted;если спелл уже применен

if ( MenuMode == 1 )
return
endif
if ( globalwarm == 0 );если снаружи не тепло, выходим сразу - делать нам больше нечего
return
endif
;этот блок не даёт скрипту работать чаще чем раз в 2 секунды, теоретически;)
if ( timergl <= 2 ); насчитал пока меньше 5сек
set timergl to timergl + GetSecondsPassed; пусть считает, а то он считал только если не считает, вот такой бред.
MessageBox "Debug: timer is %f", timer;покажем скока же он насчитал
else;а если насчитал больше 2сек
MessageBox "Debug: timer is OK now";пусть напишет нам смску
set timergl to 0;и снова начнёт считать с 0
set casted to 0;начинаем каст заново
endif
;---------------------------------------------------------------
if(casted == 1); если кастанули, выходим.
return
endif

elseif ( globalwarm >= 3 );Если слишком жарко
MessageBox "Вы горите!";сообщим игроку
Cast, Firepit_bad_spell, Player;добавим плохой эффект
set casted to 1;кастанули
set globalwarm to 0
elseif ( globalwarm >= 1 );если тепло нормальное
MessageBox "Вы чувствуете живительное тепло костра...";сообщим игроку
Cast, Firepit_good_spell, Player;добавим хороший эффект
set casted to 1;кастанули
set globalwarm to 0
endif
End

 

Итак, мы имеем:

1)глоб. переменную globalwarm , к которой каждый костер раз в 2 секунды прибавляет количество тепла от себя при помощи локального скрипта, вешаемого на костер. Где вводить глоб переменные, знаешь?

2)этот самый локальный скрипт

3)глобальный скрипт, который при наличии снаружи тепла раз в те же самые 2 секунды кастует на игрока заклинание и обнуляет глобальную переменную.

 

Можно, конечно, поизвращаться, сделав таймер глобальным, но мне лень.

 

Если кто опытный найдет ошибку - напишите, я исправлю.

 

Про подушки потом напишу, но там тоже через глоб переменную, к которой прибавляется 1 если мы сидим на этой подушке, и глоб скрипт, который, если переменная больше нуля, дает нам эффект сидения.

Изменено пользователем Serg9408
Ссылка на комментарий
Поделиться на другие сайты

про подушки я там просто добавлю проверку на локалбный done он чтобы спелл не снимался с игрока каждый фрейм, done ещ у каждой подушки свой будет и сделаю сидение не через getdistance а через GetCollidingPC (кстати тоже с делаю и с повреждениями костра, тогда останеться прописать условия только для благоприятного расстояния)

 

а в скрипте твоём есть один большой косяк, если вокруг меня будет костров 5 я сгорю даже не расстоянии 300

 

внимание вопрос: как кастануть на игрока заклинание, не применяя функцию addspell, так чтобы заклинание каставалось не каким либо объектом из мира. тоесть грубо говоря "никто наложил на ГГ заклинание типа "касание". Насколько я помню, игрока нельзя скриптами заставить кастовать заклинания?

Ссылка на комментарий
Поделиться на другие сайты

На расстоянии 300 от каждого костра? С расстояниями и количеством тепла можно подшаманить, чтобы лучше было. А так - да, тепло от всех костров складывается, и можно сгореть, не подходя вплотную ни к одному.
Ссылка на комментарий
Поделиться на другие сайты

На расстоянии 300 от каждого костра? С расстояниями и количеством тепла можно подшаманить, чтобы лучше было. А так - да, тепло от всех костров складывается, и можно сгореть, не подходя вплотную ни к одному.

 

Конечно от каждого, хотя я понял как можно исправить:

elseif ( GetDistance, Player <= 32 );Если слишком близко
set warmhere to 15
set done to 1
elseif ( GetDistance, Player <= 100 );если расстояние среднее
set warmhere to 3
set done to 1
elseif ( GetDistance, Player <= 300 );если мы все же на оптимальном расстоянии
set warmhere to 1
set done to 1
endif

if ( globalwarm >= 15 );Если слишком жарко
MessageBox "Вы горите!";сообщим игроку
Cast, Firepit_bad_spell, Player;добавим плохой эффект
set casted to 1;кастанули
set globalwarm to 0
elseif ( globalwarm >= 1 );если тепло нормальное
MessageBox "Вы чувствуете живительное тепло костра...";сообщим игроку
Cast, Firepit_good_spell, Player;добавим хороший эффект
set casted to 1;кастанули
set globalwarm to 0
endif

 

эт уже ближе к реальности, от 15 костров ты точно сгоришь=) или от 5 но поближе

Ссылка на комментарий
Поделиться на другие сайты

Да там вообще можно серьезно поизмываться... например, поставить обратную квадратичную функцию в духе

if(getdistance, player<= 300)

set warmhere to 500/(getdistance, player)/(getdistance, player) ;не знаю, поймет ли он такое

endif

коэффициенты все настраиваются + еще как-нибудь можно.

 

А в реальности, что, от 15 костров вблизи не сгоришь?

Ссылка на комментарий
Поделиться на другие сайты

как кастануть на игрока заклинание, не применяя функцию addspell

Вот в глобальном скрипте можно спокойно добавлять/удалять с проверкой проклятия или хар-ки. То что у тебя было в первых постах. И костер не будет плеваться.

 

if ( Player -> GetSpellEffects, "Firepit_bad_spell" == 0 )

Player -> AddSpell "Firepit_bad_spell"

endif

 

Интервал можно уменьшить до 1 сек.

А глобальную переменную не задавай/обнуляй сразу, а увеличивай/уменьшай, скажем на +1,+3,+15 и -10.

 

В локальном при увеличении, если скрипт не рунинг, то старт скрипт,

а в глобальном - когда ноль стоп скрипт.

 

Это сэкономит процессорное время.

Ссылка на комментарий
Поделиться на другие сайты

  • 3 месяца спустя...

спс всем кто откликнулся отдельно olol'у, проверю такой вариант если получится то в скором времени будет плаг...

 

теперь вопрос по другому скрипту:

вкрацце: это активатор управления шахтой (в данном случае эбонитовой), менюшка позволяет:

  • продать весь эбонит со склада за стоимость = цена 1 куска * количество кусков * 90% (типа рабочим тоже платить надо вот на 10% дешевле и выходит)
  • взять часть эбонита со склада для своих нужд
  • разработать ещё месторождения (это нужно для работы глобального скрипта, фактически увеличевается ежедневный прирост эбонита, короче тут багов нет)

вот первые два пункта у меня почему то не удались=(

прим.: склад это всеголишь глобальная переменная которая раз в сколько то дней пополняется через глобальный скрипт на некоторое число кусков эбонита.

begin _dyx_mcb_e_sc

;===========================================================
;объявим переменные
;===========================================================
;long nowsellprice ;моментальная цена продажи. уже глобальная
short state
short button
;long the_x ;просто какое-то неизвестное. уже глобальная
;sklad_e и kolvo_e глобальные
;===========================================================
;активация, меню1
;===========================================================
if (state == 0)
if (OnActivate == 1)
set NowSellPrice to sklad_e*200*0.9	;устанавливаем стоимость продажи для имеющегося количества эбонита 
set state to 1
endif
endif
if (State == 1);активировали, появляется менюшка1
messagebox "У Вас в шахте %.0f месторождений эбонита и %.0f едениц эбонита (общей стоимостью %.0f) на складе. Что вы хотите сделать?", kolvo_e, sklad_e, NowSellPrice, "Продать все оптом", "Взять на реализацию", "Разработать еще месторождения (16800 дрэйков)", "Ничего"
set state to 10
endif
;===========================================================
;кнопки меню1
;===========================================================
if (state == 10)
set button to GetButtonPressed
if ( button == 0 )	;продаем весь эбонит
	if (sklad_e == 0)	;а есть ли он?
		messagebox "На складе пусто! Нечего брать!"
	else	;есть
	set NowSellPrice to sklad_e*200*0.9		;я даже ещё раз пересчитал сколько будет стоить продать весь эбонит
	[color="#FF0000"]player -> additem "gold_100", NowSellPrice[/color]	;игрок получает расчитанную сумму... теоретически... по факту какого то уха игра выдает ошибку "не может быть = 0" и дает только 1 золотой
	PlaySound "Item Gold Up"			;звук передачи денег
	set sklad_e to 0				;опустошаем склад
	endif
	set state to 1					;возврат к меню1
elseif (button == 1) 					;берем на реализацию
	set the_x to sklad_e			;выставляем х в величину того что есть на складе
	set state to 20					;переходим в меню2
elseif (button == 2) 					;покупаем месторождение (это работает нормально, так что не описываю)
	if ( player -> getitemcount "gold_001" >= 16800 )
		player -> removeitem "gold_001" 16800			
		PlaySound "Item Gold Up"
		set kolvo_e to kolvo_e+1
	else
		messagebox "У вас недостаточно денег! Вам надо 16800 дрэйков чистой наличкой, акции, чеки и самоцветы не принимаются!"
	endif
	set state to 1
elseif (button == 3) 					;отменяем
	set state to 0
	return
endif
endif
;===========================================================
;меню2
;===========================================================
if (state == 20)							;если был запрос на переход к меню2
	if (sklad_e == 0)					;а на складе нихуя нет
		messagebox "На складе пусто! Нечего брать!"	;посылаем игрока в...
		set state to 1					;меню1
	else							;иначе появляеться меню2
	messagebox "Сколько берем? (снимаем: %.0f на складе: %.0f)", the_x, sklad_e, "+1", "+10", "-10", "-1", "Ок", "отмена"
	set state to 30						;переходим к действиям меню 2
	endif
endif
;===========================================================
;кнопки для меню2
;===========================================================
if (state == 30)			;если нас послали в действия меню2
set button to GetButtonPressed	;смотрим че за кнопка была нажата (кнопки с 0 по 3 работают норм, так что не расписываю подробно)
if ( button == 0 )				;если "+1"
	if (the_x >= sklad_e)			;и если х больше чем есть на складе
		set the_x to sklad_e		;то пусть х будет равно количеству руды на складе
		playsound "Item Ring Up"	;сообщим игроку звуком что он достиг края изменения числа х (а то испугаеться что игра зависла)
	else
		set the_x to the_x+1		;ну а если с числом х все в порядке, то увеличим его на 1
	endif
	set state to 20
elseif (button == 1)				;аналогично для кнопки "+10"
	if (the_x >= sklad_e)
		set the_x to sklad_e
		playsound "Item Ring Up"
	else
		set the_x to the_x+10
	endif
	set state to 20
elseif (button == 2)				;аналогично для кнопки "-10"
	if (the_x <= 11)			;только тут проверяем не (х>sklad_e), а чтобы х не стало 0 или отрицательным
		set the_x to 1
		playsound "Item Ring Up"
	else
		set the_x to the_x - 10
	endif
	set state to 20
elseif (button == 3)				;аналогично для кнопки "-1"
	if (the_x <= 2)
		set the_x to 1
		playsound "Item Ring Up"
	else
		set the_x to the_x-1
	endif
	set state to 20
elseif (button == 4)				;а вот с кнопкой "ок" что то не то
	set the_x to the_x			;я даже пытался поновой вызвать х, но очевидно она слетает в 0 где то раньше этого места
	[color="#FF0000"]player -> additem "ingred_raw_ebony_01" the_x [/color];вот на эту строку игра материться мол "х у вас равно 0 а команда аддайтем не может применяться с числом 0"
	set sklad_e to sklad_e - the_x		;дальше убираем со склада то число руды которое мы забрали (как ни странно но оно работает, хотя если бы х был равен 0 то ничего бы не происходило
	PlaySound "Item Gold Up"		;играем звук чтобы "типа взяли"
	messagebox "Вы взяли со склада %.0f кусков эбонита. На складе осталось %.0f кусков", the_x, sklad_e ;сообщаем игроку сколько руды он взял и сколько осталось на складе
	set state to 1				;возвращаемся в меню1
elseif (button ==5)				;ну с кнопкой "отмена" вроде проблем не обнаружено
	set state to 1
	return
endif
endif

end

Ссылка на комментарий
Поделиться на другие сайты

проблема возникает только в момент снятия денег или руды, ошибка содержит текст мол команда additem не может довать 0 едениц, после чего добавляется 1 еденица (золота или эбонита, в зависимости от того, что снимаем) и скрипт зависает, причём загруска созранённой игры его не спасает приходится перезапускать игру полностью... я вообще не пойму в чём причина... такое ощущние что глобальная переменная пытается вернуть предустановленное значение из геймсэттингс (т.е. 0), причём пытается сделать это в аккурат перед снятием. я пытался подключать трибунал и бладмун проблема не исчезла... дополнял скрипт дебагмэсаджами, которые выводили значение всех переменных на каждом этапе скрипта, все значения присваиваются нормально и в момент снятия руды или денег они содержат корректные значения, но ошибка всёравно вылезает...

:sos:

Ссылка на комментарий
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...