Собираем рабочие скрипты здесь, большие и малые, легкие и сложные (Новичкам всё трудно). К скрипту прилагаем описание работы. Скрипты оформлять доступно, можно с построчными комментариями. На один пост - один скрипт (Позже, когда тема разрастется, будет сделана навигация по теме с быстрым переходом к постам)
Если скрипт не Ваш (был написан для Вас когда-то в прошлом), указывайте пожалуйста автора.
P.S. Если скрипт не рабочий, Вы пишите об этом здесь. (Только вы должны удостовериться, что скрипт действительно не работает). Далее приводим его в рабочее состояние. В теме соблюдаем чистоту.
P.P.S Оптимизация кода - важный элемент. Если Вы можете оптимизировать работу скрипта, сделайте это и выложите здесь. Исходный скрипт будет обновлен.
#41
Отправлено
- Domastir D'Morte, Gorv, werr и 4 другим это нравится
#43
Отправлено
Воспроизводим свои видео:
Синтаксис
Function PlayBink(string asFileName, bool abInterruptible = false, bool abMuteAudio = true, bool abMuteMusic = true, \ bool abLetterbox = true) native global
Пример скрипта:
Scriptname aaaTestVideo extends ObjectReference Event onActivate(ObjectReference akActionRef) Game.PlayBink("BGS_Logo.bik", false, true, true, true) Game.GetPlayer().AddItem(money, 1000) endEvent MiscObject Property money Auto
Скрипт, при активации чего-либо, воспроизводит видео, а после выдает деньги.
Пример в игре:
Сообщение отредактировал ac97: 13 апреля 2021 - 22:38
#44
Отправлено
Scriptname aaaGetReputationHunter extends ObjectReference GlobalVariable Property countRep Auto //Глобальная переменная с текущим кол-вом репутации MiscObject Property plamen Auto //Ресурс необходимый для сдачи, для прокачки репутации EVENT onActivate(objectReference actronaut) int countReputation = countRep.GetValueInt() //получаем текущее кол-во репутации int countKristall = Game.GetPlayer().GetItemCount(plamen) //получаем кол-во артефактов у персонажа на руках. if(countReputation >= 0 && countReputation < 500 && countKristall >= 1) countRep.Value += 25 Game.GetPlayer().RemoveItem(plamen, 1) //Если репутации до 500 и есть артефакт для прокачки, то добавляем 25 репутации и удаляем артефакт elseif(countReputation <= 1000 && countReputation >= 500 && countKristall >= 2) countRep.Value += 25 Game.GetPlayer().RemoveItem(plamen, 2) //Если репутации от 500 и до 1000 и есть артефакт для прокачки, то добавляем 25 репутации и удаляем артефакт elseif(countReputation <= 2000 && countReputation >= 1000 && countKristall >= 3) countRep.Value += 25 Game.GetPlayer().RemoveItem(plamen, 3) //Если репутации от 1000 и до 2000 и есть артефакт для прокачки, то добавляем 25 репутации и удаляем артефакт elseif(countReputation <= 3000 && countReputation >= 2000 && countKristall >= 4) countRep.Value += 25 Game.GetPlayer().RemoveItem(plamen, 4) //Если репутации от 2000 и до 3000 и есть артефакт для прокачки, то добавляем 25 репутации и удаляем артефакт elseif(countReputation >= 3000) Debug.MessageBox("Максимальное кол-во репутации для сдачи. Выполните квест на получение максимальной репутации.") else Debug.MessageBox("Недостаточно Кристаллов Ящера") endif endEVENT
Скрипт для прокачки репутации любой Вами созданной гильдии. =)
Scriptname aaaShopHunters extends ObjectReference Message Property msgHunters Auto Potion Property grayPotion Auto Potion Property greenPotion Auto Potion Property bluePotion Auto Potion Property phioletPotion Auto Potion Property redPotion Auto MiscObject Property money Auto GlobalVariable Property reputation Auto EVENT onActivate(objectReference actronaut) int response = msgHunters.Show() int rep = reputation.GetValueInt() if (response == 0) if (rep >= 500 && game.getplayer().getItemCount(money) >= 50) Game.GetPlayer().RemoveItem(money, 50) Game.GetPlayer().AddItem(grayPotion, 1) else Debug.MessageBox("Недостаточно денег или репутации") endif elseif (response == 1) if (rep >= 1000 && game.getplayer().getItemCount(money) >= 70) Game.GetPlayer().RemoveItem(money, 70) Game.GetPlayer().AddItem(greenPotion, 1) else Debug.MessageBox("Недостаточно денег или репутации") endif elseif (response == 2) if (rep >= 2000 && game.getplayer().getItemCount(money) >= 100) Game.GetPlayer().RemoveItem(money, 100) Game.GetPlayer().AddItem(bluePotion, 1) else Debug.MessageBox("Недостаточно денег или репутации") endif elseif (response == 3) if (rep >= 3000 && game.getplayer().getItemCount(money) >= 150) Game.GetPlayer().RemoveItem(money, 150) Game.GetPlayer().AddItem(phioletPotion, 1) else Debug.MessageBox("Недостаточно денег или репутации") endif elseif (response == 4) if (rep >= 4000 && game.getplayer().getItemCount(money) >= 300) Game.GetPlayer().RemoveItem(money, 300) Game.GetPlayer().AddItem(redPotion, 1) else Debug.MessageBox("Недостаточно денег или репутации") endif elseif (response == 5) else Debug.MessageBox("Error") endif endEVENT
Реализация репутационного магазина, для покупки товаров с кол-вом репутации данной гильдии.
#45
Отправлено
String Function IntToHexString(Int Value) Bool Negative = (Value < 0) Int Temp01 = Math.Abs(Value) as Int Int Temp02 = 0 Int Temp03 = 0 String TempResult = "" While (Temp01 != 0) Temp02 = Math.Floor(Temp01 / 16) Temp03 = Temp01 - 16 * Temp02 TempResult = TempResult + StringUtil.GetNthChar("0123456789ABCDEF", Temp03) Temp01 = Temp02 EndWhile String Result = "" Int Index = StringUtil.GetLength(TempResult) While (Index > 0) Index = Index - 1 Result = Result + StringUtil.GetNthChar(TempResult, Index) EndWhile If (Negative) Return ("-" + Result) EndIf Return Result EndFunction
Перевод из Hex в Dec (String в Int, пример: "A56BC7" ➔ 10841031):
Int Function HexStringToInt(String Value) Int Result = 0 Bool Negative = (StringUtil.GetNthChar(Value, 0) == "-") Int Index = 0 Int ValueLength = StringUtil.GetLength(Value) While (Index < ValueLength) String Char = StringUtil.GetNthChar(Value, Index) Int Pos = StringUtil.Find("0123456789ABCDEF", Char, 0) If (Pos != -1) Result += Pos * Math.Pow(16, ValueLength - Index - 1) as Int EndIf Index += 1 EndWhile If (Negative) Return -Result EndIf Return Result EndFunction
Поддерживаются отрицательные числа. Требуется SKSE из-за StringUtil. Примеры использования:
String ValueHex = IntToHexString(481516) ; "758EC" Int ValueDec = HexStringToInt("ABC123") ; 11256099
————————————
don't forget your falls
————————————
#46
Отправлено
ScriptName SetPerkPointsScript Extends ReferenceAlias Event OnInit() RegisterForMenu("Console") ; Debug.Trace("[SetPerkPointsScript] console menu registered") EndEvent Event OnMenuOpen(String MenuName) RegisterForKey(28) ; enter RegisterForKey(156) ; num enter ; Debug.Trace("[SetPerkPointsScript] key 28 (enter) and key 156 (num enter) registered") EndEvent Event OnMenuClose(String MenuName) UnregisterForAllKeys() ; Debug.Trace("[SetPerkPointsScript] all keys unregistered") EndEvent Event OnKeyDown(Int KeyCode) ; Debug.Trace("[SetPerkPointsScript] key 28 (enter) or key 156 (num enter) pressed") Int CommandIndex = UI.GetInt("Console", "_global.Console.ConsoleInstance.Commands.length") - 1 ; Debug.Trace("[SetPerkPointsScript] Int CommandIndex >> " + CommandIndex as String) String LatestCommand = UI.GetString("Console", "_global.Console.ConsoleInstance.Commands." + CommandIndex as String) ; Debug.Trace("[SetPerkPointsScript] String LatestCommand >> " + LatestCommand) String[] CommandParts = StringUtil.Split(LatestCommand, " ") ExecCommand(CommandParts[0], CommandParts) EndEvent Function ExecCommand(String CommandName, String[] CommandArray) ; Debug.Trace("[SetPerkPointsScript] String CommandName >> " + CommandName) If (CommandName == "SetPerkPoints") || (CommandName == "SPP") If (CommandArray.Length == 2) Int PointsToSet = CommandArray[1] as Int If (PointsToSet < 0) PointsToSet = 0 ElseIf (PointsToSet > 255) PointsToSet = 255 EndIf Game.SetPerkPoints(PointsToSet) ConsoleUtil.PrintMessage("Player perk points count successfully set to " + PointsToSet as String) Else ConsoleUtil.PrintMessage("Error! Wrong function syntax. Usage:\nSetPerkPoints <int>\nSPP <int>") EndIf EndIf EndFunctionСкрипт прикрепляется к alias'у с игроком в квесте, который стартует при первой установке мода. При нажатии клавиши Enter или Num Enter будет запущена функция ExecCommand с двумя аргументами - названием команды и массивом из всех элементов команды. Так, в моём примере при вводе команды "spp 136" функции будут переданы аргументы "spp" и ["spp", "136"]. Обратите внимание, что все аргументы строковые, так что вам может потребоваться каст.
————————————
don't forget your falls
————————————
#47
Отправлено
Int[] Function ColorToRGB(Int Value) Int[] Result = New Int[3] Result[0] = Math.RightShift(Math.LogicalAnd(Value, 0xFF0000), 16) ; red Result[1] = Math.RightShift(Math.LogicalAnd(Value, 0xFF00), 8) ; green Result[2] = Math.RightShift(Math.LogicalAnd(Value, 0xFF), 0) ; blue Return Result EndFunction
Этот вид функции полностью рабочий, но я привёл его таким, лишь чтобы показать алгоритм действий. Если подумать, то смещение на 0 бит не имеет смысла, как и "логическое И" с 0xFF0000 в связке со смещением на 16 бит. Без "логического И" ABCDEF после смещения превращается в AB.CDEF, которое сразу обрезается до AB из-за типа данных Int. Таким образом, более оптимальный вид функции будет таким:
Int[] Function ColorToRGB(Int Value) Int[] Result = New Int[3] Result[0] = Math.RightShift(Value, 16) ; red Result[1] = Math.RightShift(Math.LogicalAnd(Value, 0xFF00), 8) ; green Result[2] = Math.LogicalAnd(Value, 0xFF) ; blue Return Result EndFunction
Пример использования:
Int[] RGB = ColorToRGB(10092543) ; [153, 255, 255]
————————————
don't forget your falls
————————————
#48
Отправлено
Когда в SkyUI вы используете настройку типа OptionColor (выбор цвета из небольшой палитры), то мод возвращает цвет в формате Int (целое число). Например, светло-голубой цвет будет иметь значение 10092543. Вам может понадобиться вытащить из этого значения числа RGB, для чего некоторые предлагают операции деления, вычитания или целого остатка. Да, эти методы рабочие, но это квадратно-гнездовой способ мышления, когда есть битовые операции. Выглядит это вот так:
Int[] Function ColorToRGB(Int Value) Int[] Result = New Int[3] Result[0] = Math.RightShift(Math.LogicalAnd(Value, 0xFF0000), 16) ; red Result[1] = Math.RightShift(Math.LogicalAnd(Value, 0xFF00), 8) ; green Result[2] = Math.RightShift(Math.LogicalAnd(Value, 0xFF), 0) ; blue Return Result EndFunctionЭтот вид функции полностью рабочий, но я привёл его таким, лишь чтобы показать алгоритм действий. Если подумать, то смещение на 0 бит не имеет смысла, как и "логическое И" с 0xFF0000 в связке со смещением на 16 бит. Без "логического И" ABCDEF после смещения превращается в AB.CDEF, которое сразу обрезается до AB из-за типа данных Int. Таким образом, более оптимальный вид функции будет таким:Int[] Function ColorToRGB(Int Value) Int[] Result = New Int[3] Result[0] = Math.RightShift(Value, 16) ; red Result[1] = Math.RightShift(Math.LogicalAnd(Value, 0xFF00), 8) ; green Result[2] = Math.LogicalAnd(Value, 0xFF) ; blue Return Result EndFunctionПример использования:Int[] RGB = ColorToRGB(10092543) ; [153, 255, 255]
Теперь осталось реализовать структуры, классы, шаблоны да и полностью библиотеку STL =)
#49
Отправлено
Раздевает и одевает ГГ по триггеру... Если что лишнее, буду рад замечаниям...
Scriptname aaaUnequip extends ObjectReference
Import Game
Import Utility
Import Debug
Import MathFormlist Property frmList auto
Event OnTriggerEnter(ObjectReference akActionRef)
if(akActionRef == Game.GetPlayer())
actor who = akActionRef as actor
frmList.Revert()
UnequipWeaponActor(who)
UnequipItemActor(who)
endifEndEvent
EVENT OnTriggerLeave (objectReference akActionRef)
If akActionRef == Game.GetPlayer()
actor who = akActionRef as actor
EquipItemActor(who)
EndIf
EndEventFunction UnequipItemActor(Actor target)
int index
int slotsChecked
slotsChecked += 0x00100000
slotsChecked += 0x00200000 ; игнорировать зарезервированные слоты
slotsChecked += 0x80000000int thisSlot = 0x01
while (thisSlot < 0x80000000)
if (Math.LogicalAnd(slotsChecked, thisSlot) != thisSlot)
Armor thisArmor = target.GetWornForm(thisSlot) as Armor
if (thisArmor)
frmList.AddForm(thisArmor)
target.UnequipItem(thisArmor, abSilent = true)
index += 1
slotsChecked += thisArmor.GetSlotMask()
else
slotsChecked += thisSlot
endif
endif
thisSlot *= 2 ;удвоить число, чтобы перейти к следующему слоту
endWhile
EndFunctionFunction EquipItemActor(Actor akActor)
Int iIndex = frmList.GetSize()
While iIndex
iIndex -= 1
Form kForm = frmList.GetAt(iIndex) As form
akActor.EquipItem(kForm, abSilent = true)
EndWhile
frmList.Revert()
EndFunctionFunction UnequipWeaponActor(Actor target)
if (target.GetEquippedWeapon(true))
FORM twisWeapon=target.GetEquippedWeapon(true) as FORM
frmList.AddForm(twisWeapon)
target.UnequipItem(twisWeapon, abSilent = true)
endif
if (target.GetEquippedWeapon(false))
FORM twisWeapon=target.GetEquippedWeapon(false) as FORM
frmList.AddForm(twisWeapon)
target.UnequipItem(twisWeapon, abSilent = true)
endif
EndFunction
зы... нужно в ск формлист создать пустой и подключить к скриптуб, и прошу не тыкать пальцем с усмешкой. это мой первый скрипт
Решил опробовать скрипт, но словил ошибки компиляции
#50
Отправлено
Скрипт для ванны/бассейна/бадьи и т.д. Предназначен для вампиров. Если человек будет использовать, то проиграется только сообщение с отвращением и анимация.
Scriptname GK_script_bath extends ObjectReference EffectShader Property DLC1nVampireGoreFXS Auto MagicEffect Property PERKEFFECT Auto String Property Fail Auto String Property Success Auto String Property MyAnimation_01 Auto Idle Property MyAnimation_02 Auto Idle Property MyAnimation_03 Auto String Property MyAnimation_04 Auto String Property MyAnimation_05 Auto Idle Property IdleStop_Loose Auto ObjectReference Property PlayerRef Auto ObjectReference Property MovetoInside Auto ObjectReference Property MovetoOutside Auto Sound Property WashesTheBody01 Auto Sound Property WashesTheBody02 Auto Sound Property SitsInTheBath01 Auto Sound Property SitsInTheBath02 Auto Sound Property GetsUpInTheBath01 Auto Sound Property GetsUpInTheBath02 Auto Sound Property WipesOff Auto Sound Property Vomit Auto Spell Property PerkSpell1 Auto Spell Property PerkSpell2 Auto Spell Property HasVampirism Auto GlobalVariable Property GameHour Auto ImageSpaceModifier Property TG05BlackFrame Auto Event OnActivate(ObjectReference akActionRef) If akActionRef == Game.GetPlayer().HasSpell(HasVampirism) == 0 If Game.GetPlayer().IsWeaponDrawn() Game.DisablePlayerControls(abMovement =true, abFighting = true, abCamSwitch = true, abLooking = true, abSneaking = true, abMenu = true, abJournalTabs= true) Utility.Wait(1.5) Game.EnablePlayerControls(abMovement =true, abFighting = true, abCamSwitch = true, abLooking = true, abSneaking = true, abMenu = true, abJournalTabs= true) EndIf Game.DisablePlayerControls(abMovement =true, abFighting = true, abCamSwitch = true, abLooking = false, abSneaking = true, abMenu = true, abJournalTabs= true) Game.ForceThirdPerson() Utility.Wait(0.5) debug.notification(Fail) Debug.SendAnimationEvent(Game.GetPlayer(), MyAnimation_04) Vomit.Play(PlayerRef) PerkSpell2.Cast(Game.GetPlayer(), Game.GetPlayer()) Utility.Wait(1.5) Game.GetPlayer().PlayIdle(IdleStop_Loose) Game.EnablePlayerControls(abMovement =true, abFighting = true, abCamSwitch = true, abLooking = false, abSneaking = true, abMenu = true, abJournalTabs= true) Return Else If akActionRef == Game.GetPlayer().HasSpell(HasVampirism) == 1 If Game.GetPlayer().IsWeaponDrawn() Game.DisablePlayerControls(abMovement =true, abFighting = true, abCamSwitch = true, abLooking = true, abSneaking = true, abMenu = true, abJournalTabs= true) Utility.Wait(1.5) Game.EnablePlayerControls(abMovement =true, abFighting = true, abCamSwitch = true, abLooking = true, abSneaking = true, abMenu = true, abJournalTabs= true) EndIf Game.DisablePlayerControls(abMovement =true, abFighting = true, abCamSwitch = true, abLooking = false, abSneaking = true, abMenu = true, abJournalTabs= true) Game.ForceThirdPerson() Utility.Wait(0.5) Debug.SendAnimationEvent(Game.GetPlayer(), MyAnimation_05) Utility.Wait(2.0) TG05BlackFrame.ApplyCrossFade() Utility.Wait(3.5) Game.GetPlayer().UnequipAll() Game.GetPlayer().Moveto(MovetoInside) Utility.Wait(0.5) Debug.SendAnimationEvent(Game.GetPlayer(), MyAnimation_01) TG05BlackFrame.Remove() SitsInTheBath01.Play(PlayerRef) Utility.Wait(2.0) DLC1nVampireGoreFXS.Play(Game.GetPlayer()) Game.GetPlayer().PlayIdle(MyAnimation_02) GetsUpInTheBath01.Play(PlayerRef) Utility.Wait(2.7) Game.GetPlayer().PlayIdle(MyAnimation_03) WashesTheBody01.Play(PlayerRef) Utility.Wait(2.0) DLC1nVampireGoreFXS.Stop(Game.GetPlayer()) Utility.Wait(1.0) Debug.SendAnimationEvent(Game.GetPlayer(), MyAnimation_01) SitsInTheBath02.Play(PlayerRef) Utility.Wait(2.0) DLC1nVampireGoreFXS.Play(Game.GetPlayer()) Game.GetPlayer().PlayIdle(MyAnimation_02) GetsUpInTheBath02.Play(PlayerRef) Utility.Wait(2.7) Game.GetPlayer().PlayIdle(MyAnimation_03) WashesTheBody02.Play(PlayerRef) TG05BlackFrame.ApplyCrossFade() Utility.Wait(2.0) WipesOff.Play(PlayerRef) Utility.Wait(3.0) DLC1nVampireGoreFXS.Stop(Game.GetPlayer()) Game.GetPlayer().PlayIdle(IdleStop_Loose) Game.GetPlayer().Moveto(MovetoOutside) Game.EnablePlayerControls(abMovement =true, abFighting = true, abCamSwitch = true, abLooking = false, abSneaking = true, abMenu = true, abJournalTabs= true) GameHour.SetValue(GameHour.GetValue()+1) debug.notification("Прошёл один час") PerkSpell1.Cast(Game.GetPlayer(), Game.GetPlayer()) debug.notification(Success) TG05BlackFrame.Remove() EndIf EndIf EndEvent
Пример того, что будет, если бадью использует не вампир
UPD: обновил скрипт. Добавил новые анимации, кастомные звуки и изменил затемнение экрана.
Сообщение отредактировал GOLDEN_KINDER: 28 января 2022 - 07:44
#51
Отправлено
Скачивание файла в игре в папку мода. Необходимо SKSE и Address Library. По желанию, можно вообще QtFramework подключить
pch.h #pragma once // This file is required. #include "RE/Skyrim.h" #include "SKSE/SKSE.h" using namespace std::literals;
plugin.cpp #include <Urlmon.h> #include <iostream> #include <filesystem> #pragma comment (lib, "urlmon.lib") void downloader(std::string url, std::string filename) { std::wstring urlstr = std::wstring(url.begin(), url.end()); const wchar_t* urlcstr = urlstr.c_str(); std::wstring fnamestr = std::wstring(filename.begin(), filename.end()); const wchar_t* fnamecstr = fnamestr.c_str(); URLDownloadToFile(0, urlcstr, fnamecstr, 0, 0); } SKSEPluginLoad(const SKSE::LoadInterface *skse) { SKSE::Init(skse); std::string url = "https://site.ru/file.txt"; if(std::filesystem::exists("Data\\SKSE\\Plugins\\Plottering")) { SKSE::GetMessagingInterface()->RegisterListener([](SKSE::MessagingInterface::Message *message) { if (message->type == SKSE::MessagingInterface::kDataLoaded) RE::ConsoleLog::GetSingleton()->Print("Download File"); }); downloader(url, "Data\\SKSE\\Plugins\\Plottering\\file.txt"); } else { SKSE::GetMessagingInterface()->RegisterListener([](SKSE::MessagingInterface::Message *message) { if (message->type == SKSE::MessagingInterface::kDataLoaded) RE::ConsoleLog::GetSingleton()->Print("Create dir"); }); std::filesystem::create_directory("Data\\SKSE\\Plugins\\Plottering"); SKSE::GetMessagingInterface()->RegisterListener([](SKSE::MessagingInterface::Message *message) { if (message->type == SKSE::MessagingInterface::kDataLoaded) RE::ConsoleLog::GetSingleton()->Print("Download File"); }); downloader(url, "Data\\SKSE\\Plugins\\Plottering\\file.txt"); } return true; }
Сообщение отредактировал ac97: 29 июля 2023 - 21:42
#52
Отправлено
Попытка реализации классов прям как в cpp, но только в Papyrus
Пример Класса:
Scriptname PlayerClass ; Свойства String Property Name Auto Int Property Level Auto Float Property Health Auto ; Конструктороподобная функция Function Init(String name, Int level, Float health) Name = name Level = level Health = health EndFunction ; Метод класса Function PrintPlayerInfo() Debug.Notification("Player Name: " + Name) Debug.Notification("Player Level: " + Level) Debug.Notification("Player Health: " + Health) EndFunction
Пример использования класса:
Scriptname tClass extends Quest ; Свойство для хранения экземпляра класса Player PlayerClass Property PlayerInstance Auto Event OnInit() ; Создание экземпляра класса Player PlayerInstance.Init("Dragonborn", 10, 100.0) ; Вызов метода класса PlayerInstance.PrintPlayerInfo() EndEvent Function CleanupPlayerInstance() ; аналог delete из cpp PlayerInstance = None EndFunction
Темы с аналогичным тегами papyrus, collection, скрипты, готовые решения, моддинг
Моддинг →
Моддинг Oblivion →
Скрипт Для СнаряженияАвтор БесездаБойчик, 07 сен 2022 скрипты, скрипт |
|
|||
Моддинг →
Моддинг Skyrim →
Заказ на изменение домаАвтор Антенна связи с космосом, 20 апр 2022 моддинг, скайрим и 3 еще... |
|
|||
Моддинг →
Моддинг Fallout →
Мастерская Fallout 4 →
Не могу найти файл TESV_Papyrus_Flags.flgАвтор Bombero_77, 27 мар 2022 papyrus, compiler |
|
|||
Моддинг →
Моддинг Skyrim →
Попытка создания квеста. Требуется помощь...Автор Гадюка Демона, 23 фев 2021 скайрим, помощь и 3 еще... |
|
|||
Моддинг →
Моддинг Skyrim →
Скрипты внезапно начали тупить...Автор Zenturo, 29 окт 2020 skyrim, skyrim le, скрипты |
|
Количество пользователей, читающих эту тему: 1
0 пользователей, 1 гостей, 0 скрытых