The forum page where I posted my world script seems to have some attention but I wanted to create my own thread specifically to organize the world scripts and those that attach to it. The one I posted before and the script had different versions because I altered it for many games so it didn't fit together well. In addition some things weren't working when fpsc was updated.
These are free to use, even in commercial works but credit to Jonathan Blackman of DSA games (Myself).
If you have suggestions or you make a add in script please post it!
Add this to you global.lua
(Script version 1.2)
---------------------------------------------------------------------------------------------
---------------------------Uniform--Open--World--Game--Handler-------------------------------
--------------------------------------EXADION------------------------------------------------
--------------------------------------Ver-1.2------------------------------------------------
--Main Config
local UseTime = 1 -- Generally this control all of the script, if disabled, time will stop! (other functions won't work when this is off!)
local LightControl = 1 -- The time controls lighting in the enviroment!
local HungerControl = 1 -- Food/Starvation system
local ThirstControl = 1 -- Thirst/dehydration system
local AutoRegenHealth = 1 -- If the players food and thirst are more than 0 we will give them health every minute
local UseFogSystem = 1 -- Every passing hour auto change fog amounts
local AdaptiveCulling = 1 -- Call "VisibilityCheck(e)" from the objects to use this! bets to call this from default.lua! if enabled culling will be determined by max fog distance.
-- --You may still use object culling the same way with this disabled. If you do set "visibilityRange" below. In that case objects will be culled at static distance.
-- --Setting this value to 2 will fully disable culling.
local UseMoneySystem = 1 -- Use Money system
local ShowHud = 1 -- Show text Change hud
local UseRespect = 1 -- Use the respect handler
local PickupItems = 1 -- Use pickup item script
--PickupItems
local MaxPickupDistance = 250 -- How far away can the item be?
local CarryWeight = 7500 -- Maximum (generated) weight of a object that may be lifted
local MoveCollision = 1 -- Do objects use collision detection while being carried
-- Respect
local MaxRespect = 1000 -- Max respect a player can earn
local RespectCur = 500 -- Current Respect
local RespectChange = 10 -- Every hour respect changes toward the median (up or down) by this ammount.
--Time Setup
local Min = 0 -- Starting Minute
local Hour = 12 -- Starting Hour
local MinuteDelay = 1000 -- MS per minute
local MinPerHour = 20 -- Minutes in a hour
local HoursPerDay = 23 -- How many hours per day cycle (23 hours will go till 23:59)
--Date
local Day = 1 -- First or current day of the week
local Week = 1 -- Starting week of the year
local DayPerWeek = 7 -- How many days in a week?
local DayNames = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"} -- Day Names
--Money
local CurrencyName = "$" -- Name of currency for use in HUD display (if activated)
local CurrencyAmt = 10000 -- Ammount of money the player starts with
local regularIncome = 1000 -- Your player earns this each game week
local Payday = "Wednesday" -- Day of the week player recieves income (use either name or day number)
-- Fog setup
local MaximumFogDistance = 10000 -- Fog is opaque at this distance
local MinimumFogDistance = 4000 -- Start of fog
local FogAdjust = 1000 -- Minimum distance between Min and max
--Lighting setup
local MaximumLighting = 200 -- Max Brightness (in normal game day)
local MinimumLighting = 0 -- Darkest it gets (in normal game day)
--Hunger setup
local Maxfood = 1000000 -- Max you can get
local Food = 100000 -- How much you start with or have
local ConsumedPerMin = 1 -- How much used each minute
local Firstwarning = .5 -- Percent of food before warning
local FirstwarningMessage = "Getting a little hungry!" -- Message to player
local Secondwarning = .25 -- Percent of food before warning
local SecondwarningMessage = "Getting very hungry!" -- Message to player
local StarvingMessage = "I am starving!" -- Message to player
local FoodLoseHealth = 1 -- How much health is taken each minute
local NotHungryMessage = "I'm not hungry" -- Your not hungry
--Thirst setup
local MaxThirst = 100000 -- Max you can get
local Thirst = 100000 -- How much you start with or have
local TConsumedPerMin = 10 -- How much used each minute
local TFirstwarning = .5 -- Percent of Thirst before warning
local TFirstwarningMessage = "Getting a little thirsty!" --Message to player
local TSecondwarning = .25 -- Percent of thirst before warning
local TSecondwarningMessage = "Getting very thirsty!" -- Message to player
local DehydratedMessage = "I am dehydrated!" -- Message to player when thirsty
local ThirstLoseHealth = 1 -- How much health is taken each minute
local NotThirstyMessage = "I'm not thirsty" -- your not hungry
--AutoRegen
local RegenHealth = 1 -- How much health is regenerated each minute!
local RegenHealthCap = 550 -- AutoRegen wont go higher than this ammount.
local RegenCap = 1 -- Does autoregen have a cap?
--Health Other
local CapHealth = 1 -- Use Max Health Cap
local MaxHealthCap = 750 -- Prevent Player health from exceeding this for any reason
--Object culling
local visibilityRange = 500 -- Set max visual range. (only used if adaptive culling is off!)
-- Water culling
VisibilityWaterMul = 1 -- If your triggere zone covers a large body of water, visibility is calculated from center, we may need to use a longer range to adjust for that. --Lower number will show water less and reduce processing. If water stays invisible even when your close, try upping the multiplier.
-- Also note This depends on the visible range, if using adaptive you may need to experiment on finding a good range.
-- Misc
hideground = 0 --if terrain is hidden, it will attampt to reshow when lighting changes, this should hide it.
-- Hud
local MaxHudOutPut = 3 -- How many view are in the HUD
---------------------------------------------------------------------------------------------
-----------------------------------For internal use------------------------------------------
local TimeStart = 0 -- The time the minute started
local TS = 1 -- Indicates a new min has started
local light = 0 -- Measure of light intensity
local AMPM = "" -- Hold AM Pm value
local FlashStateSwitch = 10 -- Dark first or light
local FogNearestSetting = 0 -- Save and retrieve distance for fog
local FogFurthestSetting = 0 -- Save and retrieve distance for fog
local FirstLoop = 1 -- Used to determin if this is the first run instance (sets things up).
local waterVisible = 0 -- Keeps track of visible status so its only set once.
local CurDayName = "" -- Day of the week name
local HudStamp = 3 -- stores current loop
local ThirstState = 0 -- Used for hud message
local HungerState = 0 -- Used for hud message
local HudFoodHunger1 = "" -- Hud Decides What message to give.
local HudFoodHunger2 = "" -- Hud Decides What message to give.
local MaxHudOutPut = 4 -- How many view are in the HUD
local IsHolding = 0 -- Object is being held.
local pickupmin = nil -- store minute item was picked up
local objNum = -1 -- Stores held object's ID
local CurItemWeight = 0 -- Stores weight of current item carried. This is either the current carried, the last carried or last attempted to lift.
--Special Prameters
local Dream = 0 -- Dream mode is enabled (Disables day/night lighting)
local Flash = 0 -- Causes screen flash (Disables day/night lighting)
local FlashDarkest = 100 -- Darkest Flash ammount between 0 - 255
local FlashBrightest = 200 -- Brightest Flash ammount between 0 - 255
local DarkZone = 0 -- Is darkzone on?
local DZIntensity = 0 -- How dark is a darkZone
---------------------------------------------------------------------------------------------
------------------------------------Start Functions------------------------------------------
--Display hunger/Thirst Hud menu
function HudHungerThirst()
if ThirstControl == 1 then
if ThirstState == 0 then
HudFoodHunger1 = NotThirstyMessage
end
if ThirstState == 1 then
HudFoodHunger1 = TFirstwarningMessage
end
if ThirstState == 2 then
HudFoodHunger1 = TSecondwarningMessage
end
if ThirstState == 3 then
HudFoodHunger1 = DehydratedMessage
end
else
HudFoodHunger = ""
end
if HungerControl == 1 then
if HungerState == 0 then
HudFoodHunger2 = NotHungryMessage
end
if HungerState == 1 then
HudFoodHunger2 = FirstwarningMessage
end
if HungerState == 2 then
HudFoodHunger2 = SecondwarningMessage
end
if HungerState == 3 then
HudFoodHunger2 = StarvingMessage
end
else
HudFoodHunger = ""
end
if ThirstControl == 1 and HungerControl == 1 then
Prompt ("Food:" .. Food .. " Thirst:" .. Thirst .. " I am " .. HudFoodHunger1 .. " and " .. HudFoodHunger2, MinuteDelay)
end
if ThirstControl == 1 and HungerControl == 0 then
Prompt ("Thirst:" .. Thirst .. " I am " .. HudFoodHunger1, MinuteDelay)
end
if ThirstControl == 0 and HungerControl == 1 then
Prompt ("Food:" .. Food .. " I am " .. HudFoodHunger2, MinuteDelay)
end
if ThirstControl == 0 and HungerControl == 0 then
--Nothing to do
end
end
function hudscript() -- Main part of the hud scripts.
if ShowHud == 1 then
if HudStamp == 4 then
if UseRespect == 1 then
Prompt ("I have " .. RespectCur .. "/" .. MaxRespect .. " respect.")
end
elseif HudStamp == 3 then
if UseMoneySystem == 1 then
Prompt ("I have " .. CurrencyName .. CurrencyAmt)
end
elseif HudStamp == 2 then
HudHungerThirst()
elseif HudStamp == 1 then
Prompt ("Today is " .. CurDayName .. ", " .. Day .. " of week " .. Week .. ". The time is" .. Hour .. ":" .. Min .. AMPM, MinuteDelay*20)
end
end
end
function FoodHandler()
if HungerControl == 1 then
if Food > Maxfood then
Food = Maxfood -- incase it was set above the max
end
if Food <= 0 then
--Prompt (StarvingMessage)
HungerState = 3
Food = 0
SendMessageI("hurtplayer",e,FoodLoseHealth)
else
Food = Food - ConsumedPerMin
end
if Food < Maxfood * Firstwarning and Food > Maxfood * Secondwarning then
Prompt (FirstwarningMessage)
HungerState = 1
end
if Food < Secondwarning and Food > 0 then
Prompt (SecondwarningMessage)
HungerState = 2
end
if Food > Maxfood * Firstwarning then -- There above any warning
HungerState = 0
end
end
end
function ThirstHandler()
if ThirstControl == 1 then
if Thirst > MaxThirst then
Thirst = MaxThirst -- incase it was set above the max
end
if Thirst <= 0 then
--Prompt (DehydratedMessage)
ThirstState = 3
Thirst = 0
SendMessageI("hurtplayer",e, ThirstLoseHealth)
else
Thirst = Thirst - ConsumedPerMin
end
if Thirst < MaxThirst * TFirstwarning and Thirst > MaxThirst * TSecondwarning then
--Prompt (TFirstwarningMessage)
ThirstState = 1
end
if Thirst < TSecondwarning and Food > 0 then
--Prompt (SecondwarningMessage)
ThirstState = 2
end
if Thirst > MaxThirst * TFirstwarning then -- There above any warning
ThirstState = 0
end
end
end
function HealthHandler() -- include autoregen
if AutoRegenHealth == 1 and Food > 0 and Thirst > 0 then
if RegenCap == 1 then
if g_PlayerHealth < RegenHealthCap then
SetPlayerHealth(g_PlayerHealth+RegenHealth)
end
else
SetPlayerHealth(g_PlayerHealth+RegenHealth)
end
end
if g_PlayerHealth >= MaxHealthCap and CapHealth == 1 then
SetPlayerHealth(MaxHealthCap)
end
end
function FogHandler()
if UseFogSystem == 1 then -- An hour past, lets generate new fog settings.
math.randomseed(Hour) -- We will use game hour to seed the random
FogNearestSetting = math.random(MinimumFogDistance, ((MaximumFogDistance - 1) - FogAdjust)) -- From the min to 1 below the max (so that we have room for a max)
FogFurthestSetting = math.random((FogNearestSetting + FogAdjust), (MaximumFogDistance)) -- What ever the nearest setting was to the max choice.
SetFogNearest(FogNearestSetting)
SetFogDistance(FogFurthestSetting)
if AdaptiveCulling == 1 then
visibilityRange = FogFurthestSetting
end
end
end
function DayOccurance() -- Anything that should happen when changing to a new day!
if Hour >= HoursPerDay then -- NewDay
Hour = 0 -- Resets hour
Min = 0 -- Reset Minute
Day = Day + 1
--since we added a day
if Day == DayPerWeek then
Week = Week + 1
Day = 1
end
CurDayName = DayNames[Day]
if CurDayName == Payday or Day == Payday then
CurrencyAmt = CurrencyAmt + regularIncome
end
else -- New Hour
Hour = Hour + 1 -- Add an hour
Min = 0 -- Set min back to zero
end -- end Hour/day check
end
function LightHandler()
if Dream == 0 and Flash == 0 and DarkZone == 0 and LightControl == 1 then --Disable following code if a special state is enabled
TotalMinutesPassed = (Hour * MinPerHour) + Min -- Indicates How many Minutes have occured.
MinutesCanOccure = (HoursPerDay * MinPerHour) / 2 -- Based on the Config, How many minutes will happen. Gets brighter only half day
LightRange = MaximumLighting - MinimumLighting -- determing change range max to min
if Hour >= HoursPerDay / 2 then -- it is afternoon get darker
light = math.floor(((MinutesCanOccure - (TotalMinutesPassed - MinutesCanOccure)) / MinutesCanOccure) * LightRange + MinimumLighting) -- Calculates brightness based on the time and the given ranges.
AMPM = "PM"
else -- Morning get brighter
light = math.floor((TotalMinutesPassed / MinutesCanOccure) * LightRange + MinimumLighting) -- Calculates brightness based on the time and the given ranges.
AMPM = "AM"
end -- Done with calculating light
SetAmbienceRed(light) -- Setting ambience
SetAmbienceGreen(light)
SetAmbienceBlue(light)
SetSurfaceRed(light) --Setting surface brightness
SetSurfaceGreen(light)
SetSurfaceBlue(light)
if UseFogSystem == 1 then --We color the fog to match
SetFogRed(light)
SetFogGreen(light)
SetFogBlue(light)
end
if hideground == 1 then
HideTerrain()
HideWater()
end
end
end
function FirstLoopHandler()
if FirstLoop == 1 then -- This loop only runs once at startup. this is to prevent the first hour from not having fog or adaptive culling setup!
if UseFogSystem == 1 then -- An hour past, lets generate new fog settings.
math.randomseed(Hour) -- We will use game hour to seed the random
FogNearestSetting = math.random(MinimumFogDistance, ((MaximumFogDistance - 1) - FogAdjust)) -- From the min to 1 below the max (so that we have room for a max)
FogFurthestSetting = math.random((FogNearestSetting + FogAdjust), (MaximumFogDistance - FogAdjust)) -- What ever the nearest setting was to the max choice.
CurDayName = DayNames[Day]
SetFogNearest(FogNearestSetting)
SetFogDistance(FogFurthestSetting)
if AdaptiveCulling == 1 then
visibilityRange = FogFurthestSetting
end
FirstLoop = 0
end
end
end
------------------------------------------Main-Function--------------------------------------------------
function Time(e) -- Start the main loop function. This is the timer, "heartbeat" that controls everything.
if UseTime == 1 then
if TS == 1 then -- New Min switch on/off
TimeStart = g_Time -- Stamp time in
TS = 0 -- Mark Done
end -- End the if
if g_Time - TimeStart >= MinuteDelay then -- Determing if a minute has occured
HudStamp = HudStamp + 1 -- We need to update the HUD, a minute has passed
if HudStamp > MaxHudOutPut then
HudStamp = 1
end
FoodHandler()
ThirstHandler()
HealthHandler()
if Min >= MinPerHour then -- Add hour or not?
DayOccurance() -- check for and change days
Respect() -- Called every hour to cause adjustments.
FogHandler() -- make fog adjustments
else -- New minute
Min = Min + 1 -- add minute
end -- end min/hour check
TS = 1 -- Marks new minute So a new time stamp will occur)
LightHandler()
if Dream == 1 then
DreamState()
elseif Flash == 1 then
FlashState()
elseif DarkZone == 1 then
DarkZoneState()
end
end
end
FirstLoopHandler()
hudscript()
end
-- Other Functions --
function Respect()
if UseRespect == 1 then
RespectMedian = MaxRespect / 2
if RespectCur > RespectMedian and RespectCur - RespectChange < RespectMedian then
RespectCur = RespectMedian
elseif RespectCur < RespectMedian and RespectCur + RespectChange > RespectMedian then
RespectCur = RespectMedian
elseif RespectCur > RespectMedian then
RespectCur = RespectCur - RespectChange
elseif RespectCur < RespectMedian then
RespectCur = RespectCur + RespectChange
end
end
end
function FlashState()
if FlashStateSwitch == 1 then
SetAmbienceRed(FlashDarkest) -- Setting ambience
SetAmbienceGreen(FlashDarkest)
SetAmbienceBlue(FlashDarkest)
SetSurfaceRed(FlashDarkest) --Setting surface brightness
SetSurfaceGreen(FlashDarkest)
SetSurfaceBlue(FlashDarkest)
if UseFogSystem == 1 then --We color the fog to match
SetFogRed(FlashDarkest)
SetFogGreen(FlashDarkest)
SetFogBlue(FlashDarkest)
end
FlashStateSwitch = 0
else
SetAmbienceRed(FlashBrightest) -- Setting ambience
SetAmbienceGreen(FlashBrightest)
SetAmbienceBlue(FlashBrightest)
SetSurfaceRed(FlashBrightest) --Setting surface brightness
SetSurfaceGreen(FlashBrightest)
SetSurfaceBlue(FlashBrightest)
if UseFogSystem == 1 then --We color the fog to match
SetFogRed(FlashBrightest)
SetFogGreen(FlashBrightest)
SetFogBlue(FlashBrightest)
end
FlashStateSwitch = 1
end
end
function DreamState()
math.randomseed(os.time())
SetAmbienceRed(math.random(0, 255)) -- Setting ambience
SetAmbienceGreen(math.random(0, 255))
SetAmbienceBlue(math.random(0, 255))
SetSurfaceRed(math.random(0, 255)) --Setting surface brightness
SetSurfaceGreen(math.random(0, 255))
SetSurfaceBlue(math.random(0, 255))
end
function DarkZoneState()
SetAmbienceRed(DZIntensity) -- Setting ambience
SetAmbienceGreen(DZIntensity)
SetAmbienceBlue(DZIntensity)
SetSurfaceRed(DZIntensity) --Setting surface brightness
SetSurfaceGreen(DZIntensity)
SetSurfaceBlue(DZIntensity)
end
--------------------------------------Interactive Items---------------------------------------
--Entities
function InteractiveItem(e) -- Call this from default.lua!
if GetPlayerDistance(e) < MaxPickupDistance then
if IsHolding == 0 then
if g_Entity[e]['avoid'] ^ 2 < CarryWeight then
HideHudMenu()
CurItemWeight = math.floor(((g_Entity[e]['avoid'] ) ) )
Prompt ("Press E to carry Item.") -- Weight " .. CurItemWeight .. "SMU")
if g_KeyPressE == 1 and pickupmin ~= Min then
GravityOff(e)
if MoveCollision == 0 then
CollisionOff(e)
end
IsHolding = 1
pickupmin = Min
objNum = g_Entity[e]['obj']
end
else
if g_KeyPressE == 1 then
HideHudMenu()
CurItemWeight = math.floor(((g_Entity[e]['avoid'] ) ) )
Prompt ("Its too heavy at that distance!") -- Weight " .. CurItemWeight .. "SMU")
ShowHudMenu()
end
end
else
Prompt ("Press E to Drop.") -- Item weight " .. CurItemWeight .. "SMU")
if g_KeyPressE == 1 and pickupmin ~= Min then
GravityOn(e)
if MoveCollision == 0 then
CollisionOn(e)
end
IsHolding = 0
pickupmin = Min
ShowHudMenu()
objNum = -1
end
--Prompt (g_Entity[e]['obj'] .. "/" .. objNum)
if g_Entity[e]['obj'] == objNum then
AngPlr = g_PlayerAngY
while AngPlr > 360 do
AngPlr = AngPlr - 360
end
while AngPlr < 0 do
AngPlr = AngPlr + 360
end
x1 = g_PlayerPosX + 60*math.sin(math.rad(AngPlr))
y1 = g_PlayerPosY - 10
z1 = g_PlayerPosZ + 60*math.cos(math.rad(AngPlr))
ResetPosition(e,x1,y1,z1)
SetPosition(e,x1,y1,z1)
end
end
else
ShowHudMenu()
end
if AdaptiveCulling ~= 2 then
if GetPlayerDistance(e) <= visibilityRange then
Show(e);
return 1;
else
Hide(e);
return 0;
end;
end
end
--Water
function WaterCulling(e) --
--CheckWater
if GetPlayerDistance(e) <= visibilityRange * VisibilityWaterMul then
if waterVisible == 0 then -- Only call show if its hidden
ShowWater()
waterVisible = 1
end
else
if waterVisible == 1 then -- Only call show if its hidden
HideWater()
waterVisible = 0
end
end
end
---------------------------------------------------------------------------------------------
------------------------------------Control-Functions----------------------------------------
--Light/dark
function SetLighting(intensity) -- Allows A script to stop day night lighting and set a specific intensity.
DZIntensity = intensity
DarkZone = 1
end
function StopLighting() -- Ends the dark zone or light zone
DarkZone = 0
end
function FlashStart(DarkestI, LightestI) -- Call to start flashing
FlashDarkest = DarkestI
FlashBrightest = LightestI
Flash = 1
end
function FlashStop() -- Stop flashing
Flash = 0
end
function DreamsStart() -- Funny color changin' dreams
Dream = 1
end
function DreamStop() -- ends dreams
Dream = 0
end
--health
function SetMaxHealth(MaxHealth) -- Set maximumhealth
MaxHealthCap = MaxHealth
end
function GetMaxHealth() -- Get current maximum health
return MaxHealthCap
end
function SetMaxHealthRegen(MaxHealthRegen) -- Sets the maximum health that can be regained
MaxHealthCap = MaxHealthRegen
end
function GetMaxHealthRegen() -- Get max regen health
MaxHealthCap = MaxHealthRegen
end
--time
function SetTime(hourI, minuteI) -- Set the current Time
MaxHealthCap = MaxHealthRegen
end
function GetTimeHour() -- Get the current Hour
return Hour
end
function GetTimeMinute() -- Get the current Minute
return Min
end
--food
function AddFood(Ammount) -- Eat something
if Food + Ammount > Maxfood then
Food = MaxFood
else
Food = Food + Ammount
end
end
function SetMaxFood(Ammount) -- Alter max food
MaxFood = Ammount
end
function GetMaxFood() -- Get max food
return Maxfood
end
function GetFood() -- Get food level
return Food
end
--drink
function AddDrink(Ammount) -- Drink Something
if Thirst + Ammount > MaxThirst then
Thirst = MaxThirst
else
Thirst = Thirst + Ammount
end
end
function SetMaxThirst(Ammount) -- Alter max thirst
MaxThirst = Ammount
end
function GetMaxThirst() -- Get Max thirst
return MaxThirst
end
function GetThirst() -- Get thirst
return Thirst
end
--hud
function ShowHudMenu() -- Hud menu visible
ShowHUD = 1
end
function HideHudMenu() -- Hud menu Hidden
ShowHUD = 0
end
--Respect
function RemoveRespect(Ammount) -- take respect away (bad player)
if RespectCur - Ammount >= 0 then
RespectCur = RespectCur - Ammount
else
RespectCur = 0
end
end
function AddRespect(Ammount) -- add respect (good player)
if RespectCur + Ammount <= MaxRespect then
RespectCur = RespectCur + Ammount
else
RespectCur = MaxRespect
end
end
function SetMaxRespect(Ammount) -- Set max level of respect
MaxRespect = Ammount
end
function GetMaxRespect(Ammount) -- get max respect level
return MaxRespect
end
--money
function GetMoney() -- How much money does the player have?
return CurrencyAmt
end
function SpendMoney(Ammount) -- Take money from the player
CurrencyAmt = CurrencyAmt - Ammount
end
function GiveMoney(Ammount) -- Give money from the player
CurrencyAmt = CurrencyAmt + Ammount
end
-- Pickup item
function GetPickupDist() -- How far away can you get item at a distance
return MaxPickupDistance
end
function SetPickupDist(Ammount) -- alter distance pickup
MaxPickupDistance = Ammount
end
function SetPickupWeight(Ammount) -- alter maximum you can lift
CarryWeight = Ammount
end
function GetPickupWeight(Ammount) -- get max you can lift
return CarryWeight
end
function MoveCollision(OnOff) -- on/off bool can items collide or not.
MoveCollision = OnOff
end
function GetObjId() -- returns the id of the object being held or -1 if no object is held
return objNum
end
function GetObjweight() -- returns the weight of the object being held or most recently carried
return CurItemWeight
end
My blog site, free artwork, scripts, textures etc.
http://jadenstockartwork.blogspot.com/