во-первых, это не руководство по работе со скриптами, а скорее по устранению ошибок
Документ так и озаглавлен "Script Error: приёмы поиска ошибок", но в целом получилось своего рода пособие, дающее некоторые навыки, полезные именно при работе со скриптами.
Цитата (ItramariN)
Во-вторых по-моему, нужно еще сказать, что вначале нужно исправить самую первую ошибку в сообщении
ItramariN, ты предлагаешь просто выкинуть функцию Dist3D? Или организовать проверку валидности входящих данных в ней, вместо того, чтобы найти настоящий источник ошибки?
В большинстве случаев стоит обращать внимание на первую строку скриптового сообщения об ошибке, если она указывает на прямой источник проблемы. В данном примере всё оказалось намного сложнее. Несомненно статья ещё принесёт пользу в решении будущих проблем.
Документ так и озаглавлен "Script Error: приёмы поиска ошибок"
Это я увидел, я имел ввиду, что в твоем посте неплохо было бы сказать о чем собственно ссылка.
Цитата (dilettante)
ItramariN, ты предлагаешь просто выкинуть функцию Dist3D? Или организовать проверку валидности входящих данных в ней, вместо того, чтобы найти настоящий источник ошибки?
Я ничего не предлагаю для конкретного примера, я говорю, что вся куча ошибок в сообщении зачастую появляется по причине самой первой. Впрочем, Havcom это и так уже сказал. Ладно, это все мелочи, главное что ты сделал хороший пример по поиску и устранению ошибок в скриптах) Я люблю людей... особенно - убивать!^__^
нужно еще сказать, что вначале нужно исправить самую первую ошибку в сообщении и тогда остальные могут исчезнуть сами
Цитата (ItramariN)
Я ничего не предлагаю для конкретного примера, я говорю, что вся куча ошибок в сообщении зачастую появляется по причине самой первой.
Думаю, я понял причину недоразумения. Поэтому считаю нужным ещё раз обратить внимание на структуру самого сообщения.
Во-первых, в ОДНОМ сообщении мы получаем сведения всего об ОДНОЙ ошибке, а не о куче, как может показаться. И все эти строки это последовательность корректных шагов выполнения программы, исключая саму ошибку.
Во-вторых, и об этом я упомянул в своём разборе, хронология событий приведших к критической ошибке представлена СНИЗУ ВВЕРХ, а не сверху вниз, как принято читать обычный текст.
В любом случае, ItramariN, спасибо, что дал оценку. Havcom не в счёт, ибо он лицо заинтересованное.
Сообщение отредактировал dilettante - Суббота, 16.03.2013, 23:10
Во-вторых, и об этом я упомянул в своём разборе, хронология событий приведших к критической ошибке представлена СНИЗУ ВВЕРХ, а не сверху вниз, как принято читать обычный текст.
А вот этого я не знал и в статье как-то пропустил... извиняюсь за невнимательность) Я люблю людей... особенно - убивать!^__^
dilettante, Хороший пост, даже как-то я лучше стал разбираться с ошибками скриптов.
Добавлено (21.03.2013, 09:52) --------------------------------------------- Небольшой скрипт для поднятия аммо.паков в игре взятый из Necrovision, как все знают в Painkiller скриптах нужно прописывать все аммо.паки для оружия указывая их названия и т.д. (сами гляньте увидите). Так вот Некровиженский скрипт упрощает все эту хрень, заменяя небольшой по размеру функцией:
function CPlayer:CheckMaxAmmo() -- По поиску ищите начало скрипта! local ma = CPlayer.s_SubClass.MPMaxAmmo.Standard if MPCfg.GameplayMode == MultiplayerGameplayMode.ArcadeGame then ma = CPlayer.s_SubClass.MPMaxAmmo.Arcade end if Game.GMode == GModes.SingleGame then ma = CPlayer.s_SubClass.MaxAmmo end for i,v in self.Ammo do if ma[ i ] and v > ma[ i ] then self.Ammo[ i ] = ma[ i ] end end
for i,o in self.Ammo do self.Ammo [i]= math.floor(o) end end
Пропишите) ее в Cplayer.lua скрипте, заменив старый скрипт.
Небольшой скрипт для поднятия аммо.паков в игре взятый из Necrovision, как все знают в Painkiller скриптах нужно прописывать все аммо.паки для оружия указывая их названия и т.д. (сами гляньте увидите).Так вот Некровиженский скрипт упрощает все эту хрень, заменяя небольшой по размеру функцией:
function CPlayer:CheckMaxAmmo() -- По поиску ищите начало скрипта! local ma = CPlayer.s_SubClass.MPMaxAmmo.Standard if MPCfg.GameplayMode == MultiplayerGameplayMode.ArcadeGame then ma = CPlayer.s_SubClass.MPMaxAmmo.Arcade end if Game.GMode == GModes.SingleGame then ma = CPlayer.s_SubClass.MaxAmmo end for i,v in self.Ammo do if ma[ i ] and v > ma[ i ] then self.Ammo[ i ] = ma[ i ] end end
for i,o in self.Ammo do self.Ammo [i]= math.floor(o) end end
Пропишите) ее в Cplayer.lua скрипте, заменив старый скрипт.
P.S. выкладываю так как у меня все работает нормально, пока не проверял на Painkiller оригинале, а только на своей версии скриптах.
А зачем поднимать паки? И как упроститься их поднятие?
Doctor20, Этот скрипт для мододелов, которые добавляют в мод новые виды оружия. А скрипт упрощает это. Чтобы к примеру подобрать аммо.пак к новому оружию, надо прописывать его туда и только затем он будет подбираться инче зависнет игра. под аммо.паками я имел ввиду скрипт ammo.pack (все оружие) а не Мегапаки в игре! В скрипты пейна у себя глянь все поймешь сразу. - Painkiller Сайт PKRC.RU Вконтакте! - Группа по Игре Painkiller: Hell & Madness (2015)
Doctor20, Этот скрипт для мододелов, которые добавляют в мод новые виды оружия. А скрипт упрощает это. Чтобы к примеру подобрать аммо.пак к новому оружию, надо прописывать его туда и только затем он будет подбираться инче зависнет игра.под аммо.паками я имел ввиду скрипт ammo.pack (все оружие) а не Мегапаки в игре! В скрипты пейна у себя глянь все поймешь сразу.
Теперь понятно. Ну я тоже правда подумал что это что-то для редактора.
Мне много раз задавали этот вопрос и вот я наконец решил немного расписать, что, да как. Тема пойдёт про то, как добавить музыку в меню.
------------------------------------------
Распишу по быстрому, что, куда добавлять, без подробностей.
LScripts/Main/Game.lua
Game = { -- _menumusic = true, -- } --====================== function Game:LoadLevel(name) -- PMENU.ActivateLoadingScreen( true, self.CurrLevel, Levels_GetSketchByDir(name), name ) PMENU.SetLoadingScreenOverall( Game:CountLevelElems(name), 10 ) ------------------ StopMenuMusic() ------------------ -- look for level file local files = FS.FindFiles(path.."*.CLevel",1,0) if table.getn(files)>0 then -- -- GObjects:AfterLoad() Game:ApplySettings() -- end ---------------------------------------------------------
LScripts/Main/Cfg.lua
Cfg = { -- MenuMusicVolume = 100, MenuMusic = true, -- } --------------------------------------------------------- LScripts/HUD/PainMenu.lua function PainMenu:Draw() if self.showStartMovies then if IsFinalBuild() then PMENU.PlayMovie('../Data/Movies/logo-dreamcatcher.bik'); PMENU.PlayMovie('../Data/Movies/logo-pcf.bik'); PMENU.PlayMovie('../Data/Movies/logo-nvidia.bik'); end
self.showStartMovies = false end
self._menumusic = name StartMenuMusic() SOUND.StreamSetVolume(3,Cfg.MenuMusicVolume)
if Cfg.MenuMusic == false then Game._menumusic = false SOUND.StreamPause(3) end end --============================== function PainMenu:SelectDifficulty(mode) ----------------------- StopMenuMusic() SOUND.StreamPause(3) ----------------------- Game:Print( "SoundTrack: "..self.movSndTrack ) if not Game.AddOn then PMENU.PlayMovie("../Data/Movies/intro.bik",self.movSndTrack) else PMENU.PlayMovie("../Data/Movies/booh_intro.bik",self.movSndTrack) end -- end --============================ -- function PainMenu:ShowNoCDWarning() -- end --======================== MenuMusicTable = { ["menustream"]={ "painkiller-mp-sacred", "C2L3_Opera_Music", } } --======================== function StartMenuMusic() if Game and Game._menumusic then local tab=MenuMusicTable[Game._menumusic] if not tab then tab=MenuMusicTable["menustream"] end
if not tab then Game:Print("menuMusicTable is empty") return end
if table.getn(tab)<1 then return end local music=tab[math.random(1,table.getn(tab))] if not music then Game:Print("[2] menuMusicTable is empty") return end
SOUND.StreamLoad(3,music) SOUND.StreamPlay(3,true) SOUND.StreamSetVolume(3,Cfg.MusicVolume) Game._menumusic=true end end --========================= function StopMenuMusic() if Game._menumusic==true then SOUND.StreamPause(3) SOUND.StreamDelete(3) Game._menumusic=false end end --========================= function PainMenu:MenuMusicOff() if self.currScreen == nil then return end
if Cfg.MenuMusic == true then SOUND.StreamResume(3) end end --============================ function PainMenu:MenuMusicVolume() if self.currScreen == nil then return end
local screen = self.currScreen local musicvol = PMENU.GetSliderValue( 'MenuMusicVolume' ) / 1
Cfg['MenuMusicVolume'] = musicvol
SOUND.StreamSetVolume(3,Cfg.MenuMusicVolume) Cfg:Save() end
LScripts/HUD/Menu/Options/SoundOptions.lua Добавляем в конец или куда угодно на ваше усмотрение новые таблицы. Слайдер для настройки громкости музыки и кнопка для включения/отключения музыки.
MenuMusicVolume = { type = MenuItemTypes.Slider, text = "MM Volume", desc = "Set the Menu Music Volume", option = "MenuMusicVolume", minValue = 0, maxValue = 100, x = 160, y = 320, action = "PainMenu:MenuMusicVolume();PainMenu:ApplyAudioSettings(false)", warning = true, },
MenuMusic = { type = MenuItemTypes.Checkbox, text = "Menu Music", desc = "Enable Menu Music", option = "MenuMusic", valueOn = true, valueOff = false, x = 650, y = 555, action = "PainMenu:MenuMusicOff()", fontBigSize = 26, warning = true, },
Продолжаем обучение. Урок второй. Как добавить кровь на экран?
LScripts/Main/Game.lua
Game = { -- Splatdf=91, _Splats={}, _Splattimeouts={}, _Splatn=16, _Splatdist=5, -- } --============== function Game:Clear(doNotReloadTemplates) -- -- Hud:Loadsplats() collectgarbage(0) end
LScripts/HUD/HUD.lua
Hud = { -- -- _splat ={}, -- } --==================== function Hud:Loadsplats() for i = 1,6 do self._splat[i]={} self._splat[i][1] = MATERIAL.Create("HUD/splat/splat_red_0"..i, TextureFlags.NoLOD + TextureFlags.NoMipMaps) for y = 1,3 do self._splat[i][y+1]=MATERIAL.Create("HUD/splat/splat_red_0"..i.."_0"..y, TextureFlags.NoLOD + TextureFlags.NoMipMaps) end self._splat[i+6]={} self._splat[i+6][1] = MATERIAL.Create("HUD/splat/splat_purple_0"..i, TextureFlags.NoLOD + TextureFlags.NoMipMaps) for y = 1,3 do self._splat[i+6][y+1]=MATERIAL.Create("HUD/splat/splat_purple_0"..i.."_0"..y, TextureFlags.NoLOD + TextureFlags.NoMipMaps) end self._splat[i+12]={} self._splat[i+12][1] = MATERIAL.Create("HUD/splat/splat_green_0"..i, TextureFlags.NoLOD + TextureFlags.NoMipMaps) for y = 1,3 do self._splat[i+12][y+1]=MATERIAL.Create("HUD/splat/splat_green_0"..i.."_0"..y, TextureFlags.NoLOD + TextureFlags.NoMipMaps) end end
for r=1, Game._Splatn do Game._Splattimeouts [r]= 0 end end --===================== function Hud:LoadData()
self:Quad(self._matHealth,Cfg.HUDSize*17*w/1024,((768+Cfg.HUDSize*14)-Cfg.HUDSize*sizey)*h/768,Cfg.HUDSize,false) ----------------------------------------------------- local y=Game._Splatn for i=1, y do if Game._Splattimeouts [i]> 0 and Game._Splats [i]then Game._Splattimeouts [i]= Game._Splattimeouts [i]- 1 if Game._Splattimeouts [i]> 3*Game.Splatdf/4 then self:QuadTrans(self._splat[Game._Splats[i].Z][1],Game._Splats[i].X,Game._Splats[i].Y,Cfg.HUDSize,false) else if Game._Splattimeouts [i]> Game.Splatdf/2 then self:QuadTrans(self._splat[Game._Splats[i].Z][2],Game._Splats[i].X,Game._Splats[i].Y,Cfg.HUDSize,false) else if Game._Splattimeouts [i]> Game.Splatdf/4 then self:QuadTrans(self._splat[Game._Splats[i].Z][3],Game._Splats[i].X,Game._Splats[i].Y,Cfg.HUDSize,false) else self:QuadTrans(self._splat[Game._Splats[i].Z][4],Game._Splats[i].X,Game._Splats[i].Y,Cfg.HUDSize,false) end end end
else Game._Splats [i]= Vector:New(math.random(w)-20,math.random(h)-20,1) end end ----------------------------------------------------- if Player then if not Player._died and not Hud.NoCrosshair then self:QuadRGBA(self._matCrosshair,w/2,h/2,self.CrossScale,true,Cfg.CrosshairR,Cfg.CrosshairG,Cfg.CrosshairB,Cfg.CrosshairTrans/100.0*255) end -- end
LScripts/Classes/CActor.lua
function CActor:CreateGib(newModel) -- local gib = MDL.MakeGib(self._Entity, ECollisionGroups.RagdollNonColliding, newModel) if gib then if Player and Dist3D(self.Pos.X,self.Pos.Y,self.Pos.Z,Player.Pos.X,Player.Pos.Y,Player.Pos.Z) < Game._Splatdist then local uu = 0 local y=Game._Splatn for l=1,y do if Game._Splattimeouts [l]< 1 and uu < 5 then local mod = 0 if self._GreenBlood then mod = 12 end if self._PurpleBlood then mod = 6 end
uu=uu+1 Game._Splattimeouts [l]= Game.Splatdf Game._Splats[l].Z = mod + math.random(6) end end end