A humble request of assistance with a script.

Discussions on Modding of S.T.A.L.K.E.R. SoC & Clear Sky

A humble request of assistance with a script.

Postby Darius6 on 26 Mar 2009 23:11

Hi guys!
Well, I finally decided to take my first foray into lua-scripting, but so far the results have been, well, non-existant.
What I am trying to do is modify some of the AMK scripts used in OL (this whole thing will hopefully be a new feature for the SmP mod).
Anyway, the basic idea is this: In AMK/OL there is the feature of displaying onscreen texture of the mask in accordance to the suit you're wearing. For example when wearing a suit equipped with a gasmask, the outlines of the mask are called onscreen to give the illusion of actually wearing one.
What I would like to accomplish is that a looped sound would be played when wearing a mask, to simulate breathing with a mask on. So far I've got some pointers and assistance from Barin on GSC forums how to go about to do this, but I haven't yet managed to actually get the sound to play. I'm guessing the actual script does activate, since when equipping a suit with a mask, there is a small pause just after equipping it. But the actual sound won't play at all. I've tried a few different approaches for this, but most of them only result in a CTD, or at best where I am now, which is that the script kicks in, but the sound won't play.
So, I decided to ask if anyone would care to take a look at the script and possibly point me to what I am doing wrong?

The script function is called by the amk_mod.script, pointing to an external script (called mask_sounds.script), which has the table for various suits and the sounds affiliated to them (currently just the same sound for all suits, might change this, if I actually get this working), and the functions for playing the sound. But for a reason unknown to me (this is my first "major" attempt at scripting), it just doesn't work. So, I ask, if someone will spot something obvious that I've done wrong, or find a better way of doing this.

Anyway, here is the code:

Code: Select all
--Gas mask breathing sound script

local suit_sounds={
--hud_gaz
svoboda_gaz_outfit_m1 = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
dolg_gaz_outfit_m1 = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
neytral_gaz_outfit_m1 = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
neytral_novice_gaz_outfit_m1 = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
svoboda_heavy_gaz_outfit_m1 = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
bandit_gaz_outfit_m1 = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
--hud_exo
neytral_exo_gaz_outfit_m1 = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
svoboda_yellow_exo_outfit_m1 = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
exo_outfit = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
--hud_merc
killer_gaz_outfit_m1 = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
--hud_sci
dolg_scientific_outfit = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
ecolog_outfit = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
protection_outfit = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
scientific_outfit = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
--hud_military
military_outfit = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
militaryspec_outfit = xr_sound.get_safe_sound_object("sounds\darius\mask_breath"),
}

local snd_left = nil
local snd_right = nil

local pos_left = vector():set(-1, 0, 1)
local pos_right = vector():set(1, 0, 1)

function start_stop_sound(suit_type)
  if snd_left ~= nil then
    snd_left:stop()
  end

  if snd_right ~= nil then
    snd_right:stop()
  end

  if suit_type and suit_sounds[suit_type] then
  snd_left = suit_sounds[suit_type]
  snd_left:play_at_pos(db.actor, pos_left, 0, sound_object.s2d + sound_object.looped)
 

  snd_right = suit_sounds[suit_type]
  snd_right:play_at_pos(db.actor, pos_right, 0, sound_object.s2d + sound_object.looped)
  end
end 


So, I've been at this for a couple of weeks, but just can't seem to make sense of whats wrong.
Any assistance would be appreciated. :mozilla_smile:

Ps: Sorry for the long post... :mozilla_oops:
Suomi Finland Perkele!
User avatar
Darius6
Senior Resident
 
Posts: 18
Joined: 13 Sep 2008 19:37
Location: Finland

Re: A humble request of assistance with a script.

Postby NatVac on 27 Mar 2009 00:08

How do you know the script is even being called? What does the calling function look like? How does the calling function get executed? How do you turn off the sound? By passing in a nil for suit_type? How do you know that's what you are doing?

If I get some time, I'll look at this, although I bet someone else has the answers. First I need to see what the amk_mod.script file looks like. I'm not sure I have a copy -- I don't have the AMK mod, and it may not be in the AIPack. Edit: But you mention it came from the OL mod -- which version?
NatVac
Resident
 
Posts: 152
Joined: 16 Sep 2008 00:13
Location: Texas

Re: A humble request of assistance with a script.

Postby Darius6 on 27 Mar 2009 00:23

Well, here is the part from amk_mod.script (I guess this is the version used by OL 2.2):
Code: Select all
local current_static
local static_enabled
local current_zoom=1
update_hud=false

function set_hud_tex(static,enabled)
  local zoom=67.5/device().fov
  zoom=(zoom-1)*1.5+1
  if zoom<1.001 then
    zoom=1.001
  end
  local stretchy=0.75/(math.floor(device().aspect_ratio*1000)/1000)
  if stretchy<1 then stretchy=1 end
  local rect={x=-768*zoom+768,y=(-512*zoom+512)*stretchy-(stretchy-1)*300,w=1024*zoom,h=768*zoom*stretchy}
  if amk.load_variable("option_hud",2)==2 then
    set_blurs(enabled and curr_tex~="hud_sci" and static~=nil,rect)
      else
    set_blurs(false,rect)
  end
  if enabled==static_enabled and current_static==static and
      zoom==current_zoom and (not update_hud) then
    return
  end
  update_hud=false
  current_zoom=zoom
  local need_change=false
  if current_static~=static then
    if current_static then
      get_hud():RemoveCustomStatic(current_static)
    end
    if static then
      get_hud():AddCustomStatic(static)
    end
    need_change=true
    current_static=static
    mask_sounds:start_stop_sound(static)
    end
   
   

   local wnd=get_hud():GetCustomStatic(current_static) and
            get_hud():GetCustomStatic(current_static):wnd()
  if (not enabled) and wnd then
    wnd:SetWidth(0)   
  elseif wnd then
    wnd:SetWndRect(rect.x,rect.y,rect.w,rect.h)
  end
  static_enabled=enabled
end


As for knowing if the script is running, I'm not entirely sure, but suits without a mask (hence, without the script functions) equip immediately, as for the ones with masks have a short "delay", the sort of I've used to seeing in SoC when a script usually "kicks in". Although, I can't be entirely sure about that.
I'm very "noob" with this stuff, so it just might be that it isn't running at all. :-??

EDIT: Hold on, that was a modified version of the script, the original function (suggested by Barin) looked like this:

Code: Select all
local need_change=false
  if current_static~=static then
    if current_static then
      get_hud():RemoveCustomStatic(current_static)
    end
    if static then
      get_hud():AddCustomStatic(static)
    end
    need_change=true
    current_static=static
  end

  if need_change then
    mask_sounds.start_stop_sound(static)
  end

Suomi Finland Perkele!
User avatar
Darius6
Senior Resident
 
Posts: 18
Joined: 13 Sep 2008 19:37
Location: Finland

Re: A humble request of assistance with a script.

Postby NatVac on 27 Mar 2009 00:40

Heh, I just extracted that mod. (There's an error with a couple of duplicated sound files; does Kanyhalos know that?) I had just downloaded it from FileFront after the news of their suspension of operation.

Okay, right off the bat:

mask_sounds.script is a script file, and the way you use functions inside a script file is via the dot, not the colon*, like so:

mask_sounds.start_stop_sound(outfit_section_name)

Edit: Heh, you edited your post. You can see that barin's original uses a period (dot) instead of the colon.

Note that there is an outfit section name there, not "static", which is a GUI object reference. (Edit: They map the section name into a HUD texture in their table called hud_tbl.) And you don't have a way to turn this off, yet.

I also suggest protecting yourself against a parsing error in your custom file:

if mask_sounds then mask_sounds.start_stop_sound(outfit_section_name) end

This says if the script object exists, then access the function within it. The object won't exist if the file has a syntax error within it.

___________
*Use the colon for object methods and C++ engine API calls; see lua_help.script.
NatVac
Resident
 
Posts: 152
Joined: 16 Sep 2008 00:13
Location: Texas

Re: A humble request of assistance with a script.

Postby Darius6 on 27 Mar 2009 01:10

Well, basically this way (as suggested by Barin) is a lot more complex than what I had in mind. Again, I only know the way in theory, can't say I could pull it off with scripting though.
But the simple solution I would like to have would be for the script to check if the hud texture is loaded, then play the sound. And if the suit is removed (and the script will remove the actual hud texture), the sound would just stop. I really don't need different sounds for various suits as an option, I'd be happy with just a generic sound for all of them (with hud textures, of course).
Also, with this method (again, in theory) this feature would turn itself off, if the player would turn off the interactive hud option from the amk options.

EDIT: And this really is my first scripting attempt (last one I did was just add the time display onscreen, and that I did by just following instructions), so it might be that I'm way over my head with this stuff. Normally I mostly just edit sounds for the game... :mozilla_oops:
Suomi Finland Perkele!
User avatar
Darius6
Senior Resident
 
Posts: 18
Joined: 13 Sep 2008 19:37
Location: Finland

Re: A humble request of assistance with a script.

Postby NatVac on 27 Mar 2009 01:31

I think you can use the enabled flag to pass a nil value into the mask_sounds.start_stop_sound() function, like so:
Code: Select all
if mask_sounds then
    if enabled then
        mask_sounds.start_stop_sound("dolg_gaz_outfit_m1")
    else
        mask_sounds.start_stop_sound(nil) --turn it off if necessary
    end
end

Replace your one line in set_hud_tex() in amk_mod.script with the above and see what happens. Tweaking is likely, but you should get sound if you put on a masked suit with the option enabled.

Edit: I hate updating this while you are reading it, but I added the test to prevent a crash if the script file didn't parse correctly.
NatVac
Resident
 
Posts: 152
Joined: 16 Sep 2008 00:13
Location: Texas

Re: A humble request of assistance with a script.

Postby Darius6 on 27 Mar 2009 01:47

NatVac wrote:I think you can use the enabled flag to pass a nil value into the mask_sounds.start_stop_sound() function, like so:
Code: Select all
if mask_sounds then
    if enabled then
        mask_sounds.start_stop_sound("dolg_gaz_outfit_m1")
    else
        mask_sounds.start_stop_sound(nil) --turn it off if necessary
    end
end

Replace your one line in set_hud_tex() in amk_mod.script with the above and see what happens. Tweaking is likely, but you should get sound if you put on a masked suit with the option enabled.

Edit: I hate updating this while you are reading it, but I added the test to prevent a crash if the script file didn't parse correctly.


Well, finally I got at least the sound playing. :) Although it plays all the time, not depending on what suit is worn. But also, it can be turned off from the AMK options along with all the other hud stuff, so this is a good start. :D Thank you!! :-bd


EDIT: Odd, when I added that if mask_sounds then, it CTD's immediately on loading a save. If I remove it, the sound plays ok, except it has no difference if you wear a suit or not. Hmm, I'll have to check the mask_sounds.script again, if I missed somehting. Also, seems the vector settings for the sound are a bit off, the sound direction changes when turning around. I'll need to tweak those. Or maybe remove the stereo setup completely and just go with one mono sound.

EDIT 2: Well, got the sound positioning fixed. Now to get the sound to play ONLY when a masked suit is equipped.
Suomi Finland Perkele!
User avatar
Darius6
Senior Resident
 
Posts: 18
Joined: 13 Sep 2008 19:37
Location: Finland

Re: A humble request of assistance with a script.

Postby NatVac on 27 Mar 2009 13:19

Hey, Darius6, don't say it CTD's without posting the [error] lines! Or you might say the log is empty, or just has a sudden "stack trace:" line and that's it, etc. The log file can tell you/me/others what needs fixing.

I have a horrible sinus headache (not like the flu problems Nightwatch and busetibi have been experiencing*), so my thinking is even more suspect at the moment. But I wonder if you left the closing "end" statement off the code block.

Give me a bit of time to look at the code; I think it would be trivial to make it start/stop on suit change.

_________
*It sounds like busetibi has found a new way to lose weight, although one would probably need to be knocked out to avoid all the suffering he went through.
NatVac
Resident
 
Posts: 152
Joined: 16 Sep 2008 00:13
Location: Texas

Re: A humble request of assistance with a script.

Postby Darius6 on 27 Mar 2009 14:55

Oh yeah, sorry about that. I had a fever and it was nearly 3am here, plus I was getting "script blind" for working on it for so long, I just simply missed the closing "end". Added that, no ctd anymore.

Still plays the sound constantly though. Also, I think I could get rid of the table for suit sounds, since I'm basically using just one sound, right? Anyway, here is the mask_sounds.script how it is currently:

Code: Select all
--Gas mask breathing sound script

local suit_sounds={
--hud_gaz
svoboda_gaz_outfit_m1 = xr_sound.get_safe_sound_object([[darius\mask_]]),
dolg_gaz_outfit_m1= xr_sound.get_safe_sound_object([[darius\mask_b1]]),
neytral_gaz_outfit_m1 = xr_sound.get_safe_sound_object([[darius\mask_breath]]),
neytral_novice_gaz_outfit_m1 = xr_sound.get_safe_sound_object([[darius\mask_breath]]),
svoboda_heavy_gaz_outfit_m1 = xr_sound.get_safe_sound_object([[darius\mask_breath]]),
bandit_gaz_outfit_m1 = xr_sound.get_safe_sound_object([[darius\mask_breath]]),
--hud_exo
neytral_exo_gaz_outfit_m1 = xr_sound.get_safe_sound_object([[darius\mask_breath]]),
svoboda_yellow_exo_outfit_m1 = xr_sound.get_safe_sound_object([[darius\mask_breath]]),
exo_outfit = xr_sound.get_safe_sound_object([[darius\mask_breath]]),
--hud_merc
killer_gaz_outfit_m1 = xr_sound.get_safe_sound_object([[darius\mask_breath]]),
--hud_sci
dolg_scientific_outfit = xr_sound.get_safe_sound_object([[darius\mask_breath]]),
ecolog_outfit = xr_sound.get_safe_sound_object([[darius\mask_breath]]),
protection_outfit = xr_sound.get_safe_sound_object([[darius\mask_breath]]),
scientific_outfit = xr_sound.get_safe_sound_object([[darius\mask_breath]]),
--hud_military
military_outfit = xr_sound.get_safe_sound_object([[darius\mask_breath]]),
militaryspec_outfit = xr_sound.get_safe_sound_object([[darius\mask_breath]]),
}

local snd_left = nil
local snd_right = nil

local pos_left = vector():set(0, 0, 0)
local pos_right = vector():set(0, 0, 0)

function start_stop_sound(suit_type)
  if snd_left ~= nil then
    snd_left:stop()
  end

  if snd_right ~= nil then
    snd_right:stop()
  end

  if suit_type and suit_sounds[suit_type] then
  snd_left = suit_sounds[suit_type]
  snd_left:play_at_pos(db.actor, pos_left, 0, sound_object.s2d + sound_object.looped)
 

  snd_right = suit_sounds[suit_type]
  snd_right:play_at_pos(db.actor, pos_right, 0, sound_object.s2d + sound_object.looped)
  end

 
end 


Oh, btw, just woke up so, good morning. :D
Suomi Finland Perkele!
User avatar
Darius6
Senior Resident
 
Posts: 18
Joined: 13 Sep 2008 19:37
Location: Finland

Re: A humble request of assistance with a script.

Postby NatVac on 27 Mar 2009 18:04

Happy belated morning to you, too.

I think the table has a use: You can identify which outfits need the breathing sound. But you might be able to get away with just the suit names without the safe_sound assignments, like so:

local suit_sounds = { svoboda_gaz_outfit_m1, dolg_gaz_outfit_m1, etc. }

You would want all the suits listed there that had masks, the ones that should have the sound.

You can use a function block that gets the suit, like the one that already exists inside check_hud() in amk_mod.script. Try changing this in set_hud_tex() (might have multiple lines there now -- this is the original code):
Code: Select all
  if need_change then
    mask_sounds.start_stop_sound(static)
  end

To this:
Code: Select all
  if need_change and mask_sounds then
    if enabled then
      local hud_outfit = db.actor:get_current_outfit()
      local hud_outfit_id = nil
      if hud_outfit then
        hud_outfit_id = hud_outfit:section()
      end
      mask_sounds.start_stop_sound(hud_outfit_id)
    else
      mask_sounds.start_stop_sound(nil)
    end
  end


Then replace this in mask_sounds.script:
Code: Select all
  if suit_type and suit_sounds[suit_type] then
  snd_left = suit_sounds[suit_type]
  snd_left:play_at_pos(db.actor, pos_left, 0, sound_object.s2d + sound_object.looped)


  snd_right = suit_sounds[suit_type]
  snd_right:play_at_pos(db.actor, pos_right, 0, sound_object.s2d + sound_object.looped)
  end

with this:
Code: Select all
  if suit_type and suit_sounds[suit_type] then
    snd_left = xr_sound.get_safe_sound_object([[darius\mask_breath]])
    snd_right = xr_sound.get_safe_sound_object([[darius\mask_breath]])
    snd_left:play_at_pos(db.actor, pos_left, 0, sound_object.s2d + sound_object.looped)
    snd_right:play_at_pos(db.actor, pos_right, 0, sound_object.s2d + sound_object.looped)
  end
NatVac
Resident
 
Posts: 152
Joined: 16 Sep 2008 00:13
Location: Texas

Re: A humble request of assistance with a script.

Postby Darius6 on 31 Mar 2009 10:51

Hmm, odd. I added the changes you suggested, but again, no sound. I also reworked the suit table in mask_sounds.script.
Suomi Finland Perkele!
User avatar
Darius6
Senior Resident
 
Posts: 18
Joined: 13 Sep 2008 19:37
Location: Finland

Re: A humble request of assistance with a script.

Postby NatVac on 31 Mar 2009 15:07

When things don't work the way you expect, you might want to add some debugging statements. For AMK it is probably of the form mylog("start_stop_sound - got here"). They will put warning messages in your console and log file when they are executed, so they can tell you if the code reached a certain section during execution.

I suspect that the new suit array is not enough. You might want to try the following in mask_sounds.script just to get sounds working. Change:

if suit_type and suit_sounds[suit_type] then

to just:

if suit_type then

If that works, then you might need to change all the masked outfit array entries to look like this:

local suit_sounds = { svoboda_gaz_outfit_m1 = true, dolg_gaz_outfit_m1 = true, etc. }

(In other words, add " = true" to each outfit.)

After that, restore the original if suit_type and suit_sounds[suit_type] then line so that you only get the sounds on the suits that have masks.
NatVac
Resident
 
Posts: 152
Joined: 16 Sep 2008 00:13
Location: Texas

Re: A humble request of assistance with a script.

Postby Darius6 on 01 Apr 2009 10:49

Ok, tried that, still doesn't work.
Didn't quite figure out where/how to add the debugging command.
Suomi Finland Perkele!
User avatar
Darius6
Senior Resident
 
Posts: 18
Joined: 13 Sep 2008 19:37
Location: Finland

Re: A humble request of assistance with a script.

Postby NatVac on 04 Apr 2009 21:33

It's hard to debug other people's code remotely by snippet inspection. If I get time I'll look at how this code is called and used.

To use the debug line, just put it in where you would like to see that the game has reached that point in the code. Change the text to be meaningful for the location. The example given was for the start_stop_sound() function in mask_sounds.script.
Code: Select all
function start_stop_sound(suit_type)
    mylog("start_stop_sound() - got here -- suit type is " .. tostring(suit_type))

The tostring() function makes anything a string for printing, even nil (empty, not defined). The two dots is used to concatenate strings.

Use debug liberally at first, to find out what is going on. Then comment them out to avoid spamming your log file, once you've determined that you are consistently reaching a certain point with good data.
NatVac
Resident
 
Posts: 152
Joined: 16 Sep 2008 00:13
Location: Texas

Re: A humble request of assistance with a script.

Postby Darius6 on 10 Apr 2009 10:13

Hmm, can't seem to get any sort of debug message to the console. Also, seems like the script (mask_sounds) isn't kicking in at all. I think when I got the sound to actually play, it was due to the call for the sound to be played being in the amk_mod.script. Although, it DID call the sound FROM the mask_sounds.script. But when trying to get the sound to be "dependent" on which suit is used, I'm running out of ideas (if I had any to start with...)

And I thought this would be simple...heh... ](*,)
This is so frustrating, that I'm considering on just abandoning the whole idea.... :(
Suomi Finland Perkele!
User avatar
Darius6
Senior Resident
 
Posts: 18
Joined: 13 Sep 2008 19:37
Location: Finland

Re: A humble request of assistance with a script.

Postby NatVac on 13 Apr 2009 20:07

Hmm. I suspect mask_sounds.script has a syntax error, now.

Use the mylog() in other places, like the amk_mod.script file. You can also place it in the mask_sounds.script file but outside of the functions to verify that the script was correctly parsed. A quick way to do this is to add a mylog() line at the very end of the file:

mylog("mask_sounds.script is valid")

Then when you load a saved game you can look at the console to see if the script file is valid. You can also see this in the log file after quitting the game. If you don't see the line, there's an error in mask_sounds.script.

Another way: Before this line in amk_mod.script:

if need_change and mask_sounds then

add these lines:
Code: Select all
  if mask_sounds then
    mylog("mask_sounds script is valid")
  else
    mylog("mask_sounds script is BROKEN")
  end

Then run the game and look at the log or console after changing a suit.
NatVac
Resident
 
Posts: 152
Joined: 16 Sep 2008 00:13
Location: Texas

Re: A humble request of assistance with a script.

Postby Darius6 on 15 Apr 2009 20:27

Hmm, I tried both, adding the debug logging to mask_sounds AND amk_mod.script. No logging whatsoever. This is truly odd. :-k
Suomi Finland Perkele!
User avatar
Darius6
Senior Resident
 
Posts: 18
Joined: 13 Sep 2008 19:37
Location: Finland

Re: A humble request of assistance with a script.

Postby NatVac on 16 Apr 2009 08:51

That sound you heard all the way across the pond was from a keyboard faceplant.

I looked at the OL 2.2 _g.script. It turns out that the mylog() debug function contains only comments, so it is essentially empty. It does absolutely nothing.

And we don't really want to make it print debug statements, because then you will see a lot of spew (AKA "spam") in the log about other unrelated things. So we will create a new function for this purpose. You will have to replace your mylog() references to dbglog().

Find the function in gamedata\scripts\_g.script that starts with this:

function mylog(msg)

Add this before that line:
Code: Select all
function dbglog(fmt, ...)
   local msg = string.format(fmt, ...)
   local msg_no_ws = string.gsub(msg, "%s", "_")
   get_console():execute("dbg:_" .. msg_no_ws)
end

Example usage:

dbglog("The suit is %s", hud_outfit:section())

But this will still work:

dbglog("The suit is " .. hud_outfit:section())

The second example doesn't need formatting via string.format(). But the function can be used to simplify the text echoed to the log file. For example, this shows the decimal value of 1 divided by 7:

dbglog("1/7 = "..tostring(1/7)) => dbg:_1/7_=_0.142857142857142857
dbglog("1/7 = %f", 1/7) => dbg:_1/7_=_0.142857

Note that in the first example, I had to convert the number to a text string, and then I used the Lua concatenation operator (..) to combine it with the original text. The second version expects a number as the argument. You could also have used "%s", as that automatically converts most types of variables to text strings for you.

Anyway, insert that function into _g.script, replace your mylog() references with dbglog(), and try again.
NatVac
Resident
 
Posts: 152
Joined: 16 Sep 2008 00:13
Location: Texas

Re: A humble request of assistance with a script.

Postby Darius6 on 16 Apr 2009 18:30

Ah, well that mylog() thing explains it, why I wasn't getting any logging.
Anyway, now I got the debug to work, although I need to specify it a bit.
Right now I'm getting the generic ! Unknown command: dbg:_mask_sounds_script_is_BROKEN message, so obviously something is not right in the script.
Anyway, glad to have some sort of debugging working, narrows down a bit where to look for the problem. :thumbright:
Suomi Finland Perkele!
User avatar
Darius6
Senior Resident
 
Posts: 18
Joined: 13 Sep 2008 19:37
Location: Finland

Next

Return to Modding Techniques

Who is online

Users browsing this forum: No registered users and 22 guests