Сейчас 21:16:16 Воскресенье, 5 мая, 2024 год
[ x ] Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Картинки В о й т и   или   з а р е г и с т р и р о в а т ь с я


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: PUVer, SirNikolas, Ty3uK  
Форум о Warcraft 3 » Раздел для картостроителей » Вопросы по картостроению » Jass: полезные функции (перенесите в библиотеку, если можно...)
Jass: полезные функции
The_ExecutorДата: Суббота, 26 Июня 2010, 14:49:04 | Сообщение # 1
3 уровень
Группа: Пользователи
Сообщений: 40
Награды: 0
Репутация: 19
Блокировки:
В этой теме публикуйте свои Jass-функции. Уверен,тема будет полезна начинающим и прогрессирующим кодерам.

FadingTextSingle. Функция, которая умеет создавать затемняющиеся тексттаги в определённой точке.

Code
function FadingTextSingle takes player p, string msg, integer red, integer green, integer blue, real x, real y, real vel, real fade, real life returns nothing
      local texttag t=CreateTextTag()
      call SetTextTagText(t,msg,0.024)
      call SetTextTagPos(t,x,y, 0.00)
      call SetTextTagColor(t,red,green,blue,255)
      call SetTextTagVelocity(t,0,vel)
      call SetTextTagVisibility(t,(GetLocalPlayer() == p))
      call SetTextTagFadepoint(t, fade)
      call SetTextTagLifespan(t, life)
      call SetTextTagPermanent(t, false)
      set t = null
endfunction

GetPlayerNameColored. Позволяет получить имя игрока в цвете. Поддерживает все 16 игроков.

Code
function GetPlayerNameColored takes player p returns string
      local playercolor col=GetPlayerColor(p)
      local string r=GetPlayerName(p)
      if GetPlayerId(p) == 12 then
          set r="the |CFF333429"+r+"|r"
      elseif GetPlayerId(p) == 13 then
          set r="the |cffc1c1ff"+r+"|r"
      elseif GetPlayerId(p) == 14 then
          set r="the |CFF333429"+r+"|r"
      elseif GetPlayerId(p) == 15 then
          set r="the |CFF333429"+r+"|r"
      elseif col == PLAYER_COLOR_RED then
          set r="|CFFFF0303"+r+"|r"
      elseif col == PLAYER_COLOR_BLUE then
          set r="|CFF0042FF"+r+"|r"
      elseif col == PLAYER_COLOR_CYAN then
          set r="|CFF1CE6B9"+r+"|r"
      elseif col == PLAYER_COLOR_PURPLE then
          set r="|CFF540081"+r+"|r"
      elseif col == PLAYER_COLOR_YELLOW then
          set r="|CFFFFFC00"+r+"|r"
      elseif col == PLAYER_COLOR_ORANGE then
          set r="|CFFFE8A0E"+r+"|r"
      elseif col == PLAYER_COLOR_GREEN then
          set r="|CFF20C000"+r+"|r"
      elseif col == PLAYER_COLOR_PINK then
          set r="|cffff80c0"+r+"|r"
      elseif col == PLAYER_COLOR_LIGHT_GRAY then
          set r="|CFF959697"+r+"|r"
      elseif col == PLAYER_COLOR_LIGHT_BLUE then
          set r="|CFF7FBFF1"+r+"|r"
      elseif col == PLAYER_COLOR_AQUA then
          set r="|cFF106246"+r+"|r"
      elseif col == PLAYER_COLOR_BROWN then
          set r="|cFF4E2A04"+r+"|r"
      else
          set r=""
      endif
      set col=null
      return r
endfunction

Trackable API. Функции для патчей 1.24+, позволяющие работать с Trackable - объектами, которые ловят мышь.

Code
function GetTrackableX takes trackable tc, hashtable h returns real   
      return LoadReal(h,GetHandleId(tc),0)
endfunction   

function GetTrackableY takes trackable tc, hashtable h returns real   
      return LoadReal(h,GetHandleId(tc),1)
endfunction   

function GetTrackableZ takes trackable tc, hashtable h returns string   
      return LoadReal(h,GetHandleId(tc),2)
endfunction   

function GetTrackableFacing takes trackable tc, hashtable h returns real   
      return LoadReal(h,GetHandleId(tc),3)
endfunction   

function GetTrackablePath takes trackable tc, hashtable h returns string   
      return LoadStr(h,GetHandleId(tc),4)
endfunction   

function GetTrackableOwner takes trackable tc, hashtable h returns player
      return Player(LoadInteger(h,GetHandleId(tc),5))
endfunction

function NewTrackable takes string path, real x, real y, real z, real facing, player owner, hashtable h returns trackable   
      local trackable tc   
      local string invisible = ""
      local destructable d = CreateDestructableZ('OTip', x, y, z, 0.00, 1.00, 0 )
      if GetLocalPlayer() != owner then
          set path = invisible
      endif
      set tc = CreateTrackable(path, x, y, facing)
      call RemoveDestructable(d)
      set d = null   
      call SaveReal(h,GetHandleId(tc),0,x)
      call SaveReal(h,GetHandleId(tc),1,y)
      call SaveReal(h,GetHandleId(tc),2,z)
      call SaveReal(h,GetHandleId(tc),3,facing)
      call SaveStr(h,GetHandleId(tc),4,path)
      call SaveInteger(h,GetHandleId(tc),5,GetPlayerId(owner))
      return tc   
endfunction

ReviveHeroTimed. Воскрешает героя спустя определённый промежуток времени.

Code
function ReviveHeroTimed_Child eakes nothing returns nothing
      local timer t = GetExpiredTimer()
      local unit hero = LoadUnitHandle(udg_Hashtable,GetHandleId(t),0)
      local real x = LoadReal(udg_Hashtable,GetHandleId(t),1)
      local real y = LoadReal(udg_Hashtable,GetHandleId(t),2)
      local boolean show = LoadBoolean(udg_Hashtable,GetHandleId(t),3)
      call ReviveHero(hero,x,y,show)
      call FludhChildHashtable(udg_Hashtable,GetHandleId(t))
      call DestroyTimer(t)
      set hero = null
      set t = null
endfunction

function ReviveHeroTimed takes unit hero, real time, real x, real y, boolean doEyeCandy returns nothing
      local timer t = CreateTimer()
      call TimerStart(t,time,false,function ReviveHeroTimed_Child)
      call SaveUnitHandle(udg_Hashtable,GetHandleId(t),0,hero)
      call SaveReal(udg_Hashtable,GetHandleId(t),1,x)
      call SaveReal(udg_Hashtable,GetHandleId(t),2,y)
      call SaveBoolean(udg_Hashtable,GetHandleId(t),3,doEyeCandy)
      set t = null
endfunction

Recipe System. Система, позволяющая скрещивать предметы одной функцией. Требует Jass New Gen Pack (vJass).

Code
library RecipeFunction

struct RecipeItems
      integer item0_id    
      integer item1_id    
      integer item2_id   
      integer item3_id    
      integer item4_id
      integer item5_id
      integer item6_id
      integer item7_id
      unit u
      item item1 = null
      item item2 = null   
      item item3 = null   
      item item4 = null
      item item5 = null
      item item6 = null
        
      method CheckItems2 takes nothing returns nothing
          local integer this_id
          local integer i = 0   
          loop
          set this_id = GetItemTypeId(UnitItemInSlot(.u, i))   
          if this_id == .item0_id then   
              set .item1 = UnitItemInSlot(.u, i)   
          elseif this_id == .item1_id then   
              set .item2 = UnitItemInSlot(.u, i)   
          endif
          set i = i + 1
          exitwhen i >= bj_MAX_INVENTORY
          endloop
          if .item1 != null and .item2 != null then   
              call RemoveItem(.item1)
              call RemoveItem(.item2)   
              call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl",.u,"overhead"))
              call UnitAddItemById(.u, .item2_id)
              set .item1 = null   
              set .item2 = null
              set .u = null
          endif
      endmethod
        
      method CheckItems3 takes nothing returns nothing
          local integer this_id   
          local integer i = 0   
          loop
          set this_id = GetItemTypeId(UnitItemInSlot(.u, i))   
          if this_id == .item0_id then   
              set .item1 = UnitItemInSlot(.u, i)
          elseif this_id == .item1_id then   
              set .item2 = UnitItemInSlot(.u, i)   
          elseif this_id == .item2_id then   
              set .item3 = UnitItemInSlot(.u, i)   
          endif
          set i = i + 1   
          exitwhen i >= bj_MAX_INVENTORY   
          endloop
          if .item1 != null and .item2 != null and .item3 != null then
              call RemoveItem(.item1)   
              call RemoveItem(.item2)
              call RemoveItem(.item3)   
              call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl",.u,"overhead")) //adds a special effect
              call UnitAddItemById(.u, .item3_id)
              set .item1 = null   
              set .item2 = null   
              set .item3 = null   
              set .u = null
          endif
      endmethod
        
      method CheckItems4 takes nothing returns nothing
          local integer this_id   
          local integer i = 0
          loop
          set this_id = GetItemTypeId(UnitItemInSlot(.u, i))
          if this_id == .item0_id then   
              set .item1 = UnitItemInSlot(.u, i)
          elseif this_id == .item1_id then   
              set .item2 = UnitItemInSlot(.u, i)
          elseif this_id == .item2_id then   
              set .item3 = UnitItemInSlot(.u, i)
          elseif this_id == .item3_id then
              set .item4 = UnitItemInSlot(.u, i)
          endif
          set i = i + 1   
          exitwhen i >= bj_MAX_INVENTORY   
          endloop
          if .item1 != null and .item2 != null and .item3 != null and .item4 != null then   
              call RemoveItem(.item1)   
              call RemoveItem(.item2)   
              call RemoveItem(.item3)
              call RemoveItem(.item4)
              call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl",.u,"overhead"))   
              call UnitAddItemById(.u, .item4_id)
              set .item1 = null   
              set .item2 = null   
              set .item3 = null   
              set .item4 = null
              set .u = null   
          endif
      endmethod
        
      method CheckItems5 takes nothing returns nothing
          local integer this_id   
          local integer i = 0
          loop
          set this_id = GetItemTypeId(UnitItemInSlot(.u, i))
          if this_id == .item0_id then   
              set .item1 = UnitItemInSlot(.u, i)
          elseif this_id == .item1_id then   
              set .item2 = UnitItemInSlot(.u, i)
          elseif this_id == .item2_id then   
              set .item3 = UnitItemInSlot(.u, i)
          elseif this_id == .item3_id then
              set .item4 = UnitItemInSlot(.u, i)
          elseif this_id == .item4_id then
              set .item5 = UnitItemInSlot(.u, i)
          endif
          set i = i + 1   
          exitwhen i >= bj_MAX_INVENTORY   
          endloop
          if .item1 != null and .item2 != null and .item3 != null and .item4 != null and .item5 != null then   
              call RemoveItem(.item1)   
              call RemoveItem(.item2)   
              call RemoveItem(.item3)
              call RemoveItem(.item4)
              call RemoveItem(.item5)
              call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl",.u,"overhead"))   
              call UnitAddItemById(.u, .item5_id)
              set .item1 = null   
              set .item2 = null   
              set .item3 = null   
              set .item4 = null
              set .item5 = null
              set .u = null   
          endif
      endmethod
        
      method CheckItems6 takes nothing returns nothing
          local integer this_id   
          local integer i = 0
          loop
          set this_id = GetItemTypeId(UnitItemInSlot(.u, i))
          if this_id == .item0_id then   
              set .item1 = UnitItemInSlot(.u, i)
          elseif this_id == .item1_id then   
              set .item2 = UnitItemInSlot(.u, i)
          elseif this_id == .item2_id then   
              set .item3 = UnitItemInSlot(.u, i)
          elseif this_id == .item3_id then
              set .item4 = UnitItemInSlot(.u, i)
          elseif this_id == .item4_id then
              set .item5 = UnitItemInSlot(.u, i)
          elseif this_id == .item5_id then
              set .item6 = UnitItemInSlot(.u, i)
          endif
          set i = i + 1   
          exitwhen i >= bj_MAX_INVENTORY   
          endloop
          if .item1 != null and .item2 != null and .item3 != null and .item4 != null and .item5 != null and .item6 != null then   
              call RemoveItem(.item1)   
              call RemoveItem(.item2)   
              call RemoveItem(.item3)
              call RemoveItem(.item4)
              call RemoveItem(.item5)
              call RemoveItem(.item6)
              call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl",.u,"overhead"))   
              call UnitAddItemById(.u, .item6_id)
              set .item1 = null   
              set .item2 = null   
              set .item3 = null   
              set .item4 = null
              set .item5 = null
              set .item6 = null
              set .u = null   
          endif
      endmethod
endstruct

function Recipe2 takes unit hero, integer i1, integer i2, integer ni returns nothing
      local RecipeItems IS=RecipeItems.create()   
      set IS.item0_id = i1   
      set IS.item1_id = i2   
      set IS.item2_id = ni   
      set IS.u = hero   
      call IS.CheckItems2()   
      call IS.destroy()   
endfunction

function Recipe3 takes unit hero, integer i1, integer i2, integer i3, integer ni returns nothing
      local RecipeItems IS=RecipeItems.create()
      set IS.item0_id = i1   
      set IS.item1_id = i2   
      set IS.item2_id = i3   
      set IS.item3_id = ni   
      set IS.u = hero   
      call IS.CheckItems3()   
      call IS.destroy()
endfunction

function Recipe4 takes unit hero, integer i1, integer i2, integer i3, integer i4, integer ni returns nothing
      local RecipeItems IS=RecipeItems.create()
      set IS.item0_id = i1   
      set IS.item1_id = i2   
      set IS.item2_id = i3   
      set IS.item3_id = i4   
      set IS.item4_id = ni
      set IS.u = hero   
      call IS.CheckItems4()   
      call IS.destroy()
endfunction

function Recipe5 takes unit hero, integer i1, integer i2, integer i3, integer i4, integer i5, integer ni returns nothing
      local RecipeItems IS=RecipeItems.create()
      set IS.item0_id = i1   
      set IS.item1_id = i2   
      set IS.item2_id = i3   
      set IS.item3_id = i4
      set IS.item4_id = i5
      set IS.item5_id = ni
      set IS.u = hero   
      call IS.CheckItems5()   
      call IS.destroy()
endfunction

function Recipe6 takes unit hero, integer i1, integer i2, integer i3, integer i4, integer i5, integer i6, integer ni returns nothing
      local RecipeItems IS=RecipeItems.create()
      set IS.item0_id = i1   
      set IS.item1_id = i2   
      set IS.item2_id = i3   
      set IS.item3_id = i4
      set IS.item4_id = i5
      set IS.item5_id = i6
      set IS.item6_id = ni
      set IS.u = hero   
      call IS.CheckItems6()   
      call IS.destroy()
endfunction

endlibrary

DistanceBetweenCoords. Находит расстояние между заданными координатами.

Code
function DistanceBetweenCoords takes real x1, real y1, real x2, real y2 returns real
     return SquareRoot((x1-x2) * (x1-x2) + (y1-y2) * (y1-y2))   
endfunction

AngleBetweenCoords.Находит угол между заданными координатами.

Code
function AngleBetweenCoords takes real xa, real xb, real ya, real yb returns real
      return 57.295827 * Atan2(yb - ya, xb - xa)
endfunction

Hex to Dec. Конвертирует число из шестнадцатеричной системы в десятичную.

Code
function H2D takes string hex returns integer
    local string abc = "0123456789abcdef"
    local integer i = 0
    local integer dec   
    loop
      set i = i + 1
      exitwhen( SubString(abc, (i-1), i)==SubString(hex, 0, 1) )
    endloop
    set dec = (i-1) * 16
    set i = 0
    loop
      set i = i + 1
      exitwhen( SubString(abc, (i-1), i)==SubString(hex, 1, 2) )
    endloop
    set dec = dec + i - 1
    return dec
endfunction

Dec to Hex. Конвертирует число из десятичной системы в шестнадцатеричную.

Code
function D2H takes integer i returns string
    local string abc = "0123456789abcdef"  
    local string s = SubString(abc, i / 16, i / 16 + 1) + SubString(abc, ModuloInteger(i, 16), ModuloInteger(i, 16) + 1)
    return s
endfunction

GetPlayerColoredIcon.Позволяет получить иконку, заполненную цветом определённого игрока.

Code
function GetPlayerColoredIcon takes player p returns string
      local playercolor pc = GetPlayerColor(p)
      local integer i = GetHandleId(pc)
      local string s
      if i < 10 then   
          set s = "0" + I2S(i)
      else   
          set s = I2S(i)
      endif
      set pc = null      
      return "ReplaceableTextures\\TeamColor\\TeamColor" + s + ".blp"
endfunction

DamageLine. Функция нанесения урона по линии. Полезна для спеллмейкеров.

Code
function DamageLine takes location a, location b, real w, real dmg, boolean ranged returns nothing
      local integer i = 0
      local real aX = GetLocationX(a)
      local real bX = GetLocationX(b)
      local real aY = GetLocationY(a)
      local real bY = GetLocationY(b)
      local real dist = SquareRoot((bX - aX) * (bX - aX) + (bY - aY) * (bY - aY))
      local real angle = 57.295827908 * Atan2(bY - aY, bX - aX)
      local group g = CreateGroup()
      local group tg = CreateGroup()
      local unit u
      loop
      exitwhen i > 2*dist/w
          call GroupEnumUnitsInRange(g, aX, aY, w, null)
          loop
              set u = FirstOfGroup(g)
              if (IsUnitInGroup(u, tg) == false) then
                  call UnitDamageTarget(u, u, dmg, true, ranged, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
              endif
              call GroupAddUnit(tg, u)
              call GroupRemoveUnit(g, u)
          exitwhen u == null
          endloop
          set aX = aX + w/2 * Cos(angle * 0.01745327)
          set aY = aY + w/2 * Sin(angle * 0.01745327)
          set i = i + 1
      endloop
      call DestroyGroup(g)
      call DestroyGroup(tg)
      set g = null
      set u = null
endfunction
 

Cool_BoyДата: Суббота, 26 Июня 2010, 14:51:23 | Сообщение # 2
8 уровень
Группа: Проверенные
Сообщений: 643
Награды: 0
Репутация: 48
Блокировки:
у меня чет твой шрифт про описание не видит, то есть он не русский какой-то

 

АхилДата: Суббота, 26 Июня 2010, 14:55:01 | Сообщение # 3
9 уровень
Группа: Проверенные
Сообщений: 831
Награды: 0
Репутация: 191
Блокировки:
Вобще в Jasse не розбираюсь. Помогите кто нить изучить Джасс. И рассказать о его возможностях. Плз!

 

АхилДата: Суббота, 26 Июня 2010, 15:01:52 | Сообщение # 4
9 уровень
Группа: Проверенные
Сообщений: 831
Награды: 0
Репутация: 191
Блокировки:
А как вобще из джасса добовлять в карту вот эти функции?

 

The_ExecutorДата: Суббота, 26 Июня 2010, 15:45:16 | Сообщение # 5
3 уровень
Группа: Пользователи
Сообщений: 40
Награды: 0
Репутация: 19
Блокировки:
В основной код карты скопировать и вставить.
 

POMA220Дата: Воскресенье, 27 Июня 2010, 03:48:19 | Сообщение # 6
6 уровень
Группа: Заблокированные
Сообщений: 152
Награды: 0
Репутация: 25
Блокировки:
Angle и Distance between points уже есть как таковые в ворлдэдиторе

Долой панд! Время tee пришло!
 

The_ExecutorДата: Воскресенье, 27 Июня 2010, 16:09:10 | Сообщение # 7
3 уровень
Группа: Пользователи
Сообщений: 40
Награды: 0
Репутация: 19
Блокировки:
Quote (Dragon93)
с этим паком иди в тему полезные функции,что в библиотеке

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

Добавлено (27-06-2010, 16:09)
---------------------------------------------

Quote (POMA220)
Angle и Distance between points уже есть как таковые в ворлдэдиторе

Это между точками, утечные. Между координатами нет таких.
 

DragoNДата: Воскресенье, 27 Июня 2010, 17:06:06 | Сообщение # 8
Инквизитор
Группа: Стримеры
Сообщений: 4348
Награды: 7
Репутация: 2776
Блокировки:
убраны ошибки в кривом описании

El Psy Congroo
 

The_ExecutorДата: Воскресенье, 27 Июня 2010, 17:56:58 | Сообщение # 9
3 уровень
Группа: Пользователи
Сообщений: 40
Награды: 0
Репутация: 19
Блокировки:
Dragon93,
Благодарю. :)
 

FaionДата: Воскресенье, 27 Июня 2010, 18:18:40 | Сообщение # 10
10 уровень
Группа: Проверенные
Сообщений: 1894
Награды: 0
Репутация: 430
Блокировки:
Quote (The_Executor)
Angle и Distance between points уже есть как таковые в ворлдэдиторе

Это между точками, утечные. Между координатами нет таких.

Там можно что бы было и между координатами.

Как то так:

Code
AngleBetweenPointsBetweenPoints(Location(x1, y1), Location(x2, y2))

А вообще молодец.


О нас думают плохо лишь те, кто хуже нас, а те кто лучше нас... Им просто не до нас.
My Project: Nindogatari
MAL
 

The_ExecutorДата: Воскресенье, 27 Июня 2010, 18:19:14 | Сообщение # 11
3 уровень
Группа: Пользователи
Сообщений: 40
Награды: 0
Репутация: 19
Блокировки:
Quote (Faion)
Location(x1, y1), Location(x2, y2)

Утечно.
 

FaionДата: Воскресенье, 27 Июня 2010, 18:21:05 | Сообщение # 12
10 уровень
Группа: Проверенные
Сообщений: 1894
Награды: 0
Репутация: 430
Блокировки:
Реальные ж не утекают Оо

О нас думают плохо лишь те, кто хуже нас, а те кто лучше нас... Им просто не до нас.
My Project: Nindogatari
MAL
 

The_ExecutorДата: Воскресенье, 27 Июня 2010, 18:22:28 | Сообщение # 13
3 уровень
Группа: Пользователи
Сообщений: 40
Награды: 0
Репутация: 19
Блокировки:
Faion,
А создаваемые две локи? (native Location takes real x, real y returns location)
 

FaionДата: Воскресенье, 27 Июня 2010, 18:22:53 | Сообщение # 14
10 уровень
Группа: Проверенные
Сообщений: 1894
Награды: 0
Репутация: 430
Блокировки:
Гадость=)

О нас думают плохо лишь те, кто хуже нас, а те кто лучше нас... Им просто не до нас.
My Project: Nindogatari
MAL
 

DragoNДата: Воскресенье, 27 Июня 2010, 18:32:13 | Сообщение # 15
Инквизитор
Группа: Стримеры
Сообщений: 4348
Награды: 7
Репутация: 2776
Блокировки:
Faion, кстати да,в итоге создаётся локация,которая не удаляется

El Psy Congroo
 

H_A_PKДата: Воскресенье, 27 Июня 2010, 19:21:28 | Сообщение # 16
Быдлокодер
Группа: Проверенные
Сообщений: 2605
Награды: 1
Репутация: 822
Блокировки:
Ну в тракеблах ты только заменил РБ на Хеш из мапы где ракетки бомбить надо, а своего чтонить ? :D

Оо насчет систем счисления , напиши функция для перевода из одной(допустим моей) в другую(тоже моей) ну типа

function SystembуCool takes string a, integer PowerA, integer i, string a2, integer PowerA2, integer i2 returns string


проклятье ляжет на любого
кто дочитает до конца
нет не дочитывай не надо
остановись ну всё капец
 

Форум о Warcraft 3 » Раздел для картостроителей » Вопросы по картостроению » Jass: полезные функции (перенесите в библиотеку, если можно...)
  • Страница 1 из 1
  • 1
Поиск:

Copyright © 2006 - 2024 Warcraft3FT.info При копировании материалов c сайта ставьте, пожалуйста, активную обратную ссылку на нас • Design by gReeB04ki ©
Хостинг от uCoz