Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Dropdown Options - Is Range Possible?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
Coreveen
Cheater
Reputation: 0

Joined: 12 May 2011
Posts: 41

PostPosted: Mon Mar 14, 2022 10:59 pm    Post subject: Dropdown Options - Is Range Possible? Reply with quote

What I mean is, is there a way to simulate a range of values?

Instead of say for example, this Moodlet dropdown being:

0:Angry
1:Angry
2:Angry
3:Angry
4:Neutral
5:Neutral
6:Neutral
7:Neutral
8:Happy
9:Happy
10:Happy

Can I make it work properly with some sort of range format such as this:

0-3:Angry
4-7:Neutral
8-10:Happy

Apologies if this has been asked or explained elsewhere, Google wasn't very helpful for me this time around.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4709

PostPosted: Tue Mar 15, 2022 12:10 am    Post subject: Reply with quote

Not as far as I'm aware. I'm not even sure it makes sense.

If you set a value to "Happy", what value does it get set to? 8, 9, or 10?

Edit: you might be able to do this with custom types, but you'd have the same problem with not knowing what exact value to write given a certain category.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 470

Joined: 09 May 2003
Posts: 25812
Location: The netherlands

PostPosted: Tue Mar 15, 2022 1:24 am    Post subject: Reply with quote

if this is about displaying values and not because of a dropdown list, then you can also override the display value with lua
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
Csimbi
I post too much
Reputation: 97

Joined: 14 Jul 2007
Posts: 3326

PostPosted: Tue Mar 15, 2022 4:36 am    Post subject: Reply with quote

I think your idea is to assign multiple values to a specific value.
So, display would work easily.
But what about the other way around? Which value to pick in the range?
You need to think this through.
I'd differentiate one happy from another. E.g. very happy, moderately happy, etc.
They are surely not the same.
And then, you have your 1:1 mapping.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 470

Joined: 09 May 2003
Posts: 25812
Location: The netherlands

PostPosted: Tue Mar 15, 2022 4:40 am    Post subject: Reply with quote

alternatively, the binary type can be applied here

Code:

0000: angry
0001: angry
0010: angry
0011: angry
0100: neutral
0101: neutral
0110: neutral
0111: neutral
1000: happy
1001: happy
1010: happy

if you set the startbit to 2 with bitlength of 2 you'll get 0 for angry, 1 for neutral and 2 for happy

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
AylinCE
Grandmaster Cheater Supreme
Reputation: 37

Joined: 16 Feb 2017
Posts: 1531

PostPosted: Tue Mar 15, 2022 8:17 am    Post subject: Reply with quote

If you're accepting guests on the thread, here's my take:

Code:
function effectFormat(ind)
aa=""
 if tonumber(ind)<4 then
  aa="Angry"
 elseif tonumber(ind)>3 and tonumber(ind)<8 then --The beginning is written as 1 low and the end as 1 high.
  aa="Neutral"
 elseif tonumber(ind)>7 and tonumber(ind)<11 then
  aa="Happy"
 end
 return aa
end

-- use
a=effectFormat(8)
print(a)

_________________
Hi Hitler Different Trainer forms for you!
https://forum.cheatengine.org/viewtopic.php?t=619279
Enthusiastic people: Always one step ahead
Do not underestimate me Master: You were a beginner in the past
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Coreveen
Cheater
Reputation: 0

Joined: 12 May 2011
Posts: 41

PostPosted: Tue Mar 15, 2022 11:20 am    Post subject: Reply with quote

Oh boy, so many advanced responses. I would consider myself pretty average when it comes to the software. Certainly not knowledgeable enough to know programming or the likes of lua scripts. I can usually decipher them well enough, but writing is a completely different story.

@AylinCE
Happily accepting guests. Would you be so kind as to tell me how I would create and insert such a script to the table to affect only the address's dropdown in question? I think I'm capable of learning that.

@ParkourPenguin & @Csimbi
You guys are right.. I didn't think that through. What would CE choose if I selected a word to change it to when they have multiple values in their range. Hmm. That definitely wouldn't work. I was simply hoping for a way to format ranges of values when displaying on the table itself, so in this example I could like, glance over at the table and see that character is in a Neutral Mood without having to guess, recall what mood the exact values represent, or check the stat values screen.

This however was just small task as I hoped to also employ this technique for other frankly ridiculously massive dropdown lists where ranges are dozens to hundreds per word category and total near or more than a thousand. Such as Bestiaries and Item ID lists, things of that nature.

@Dark Byte
It is indeed about displaying values, I didn't think the reverse through at all... my bad. I'm sorry, I don't think I understand about binary type, startbit and bit length. Really have no idea where to start learning about that, my capacity of learning isn't the greatest - but I can start with basics if you don't mind recommending somewhere to start.
Back to top
View user's profile Send private message
AylinCE
Grandmaster Cheater Supreme
Reputation: 37

Joined: 16 Feb 2017
Posts: 1531

PostPosted: Tue Mar 15, 2022 12:47 pm    Post subject: Reply with quote

Coreveen wrote:

@AylinCE
Happily accepting guests. Would you be so kind as to tell me how I would create and insert such a script to the table to affect only the address's dropdown in question? I think I'm capable of learning that.

@Dark Byte
It is indeed about displaying values, I didn't think the reverse through at all... my bad. I'm sorry, I don't think I understand about binary type, startbit and bit length. Really have no idea where to start learning about that, my capacity of learning isn't the greatest - but I can start with basics if you don't mind recommending somewhere to start.


Ok I'll continue from @DB's reference.

Let's take the value from an address and compare it with the defined morale values.
Let's change the value according to the result.

Edit morale values in the code sample.
And edit the new values to be assigned to the morale damper.

Also, I don't know how you want to activate this:
In a Trainer? at ASM? Or with Lua Script or Timer? etc.

Code:
--Edit lower and upper values

function effectFormat(ind)
aa=""
 if tonumber(ind)<1200 then
  aa="Angry"
 elseif tonumber(ind)>1199 and tonumber(ind)<4100 then --The beginning is written as 1 low and the end as 1 high.
  aa="Neutral"
 elseif tonumber(ind)>4099 and tonumber(ind)<8300 then
  aa="Happy"
 end
 return aa
end

function checkAndChange()
alist = getAddressList()

--Edit the description of the script or address to get the current value. "your address description"

 knownValue = addresslist_getMemoryRecordByDescription(alist, "your address description")
 mrl=effectFormat(tonumber(knownValue.Value))
--print(mrl)
--Edit the new values that will change based on the results.
 if mrl=="Angry" then
 --example
   knownValue.Value=2750

  elseif mrl=="Neutral" then
   knownValue.Value=6750

  elseif mrl=="Happy" then
   knownValue.Value=6750
   print("Is there an upper limit for this?\nYou are already happy!")
 end
end

_________________
Hi Hitler Different Trainer forms for you!
https://forum.cheatengine.org/viewtopic.php?t=619279
Enthusiastic people: Always one step ahead
Do not underestimate me Master: You were a beginner in the past
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4709

PostPosted: Tue Mar 15, 2022 3:19 pm    Post subject: Reply with quote

Coreveen wrote:
I was simply hoping for a way to format ranges of values when displaying on the table itself, so in this example I could like, glance over at the table and see that character is in a Neutral Mood without having to guess, recall what mood the exact values represent, or check the stat values screen.
It's probably easiest to override the display value like DB said.
Simple script:
Code:
local memrec = AddressList.createMemoryRecord()

memrec.OnGetDisplayValue = function(memoryrecord,valuestring)
  local n = tonumber(valuestring)
  if not n then return false end

  if n >= 0 and n < 4 then
    return true, valuestring .. ' (Angry)'
  elseif n >= 4 and n < 8 then
    return true, valuestring .. ' (Neutral)'
  elseif n >= 8 and n < 11 then
    return true, valuestring .. ' (Happy)'
  else
    return false
  end
end

A more generic example:
Code:
local DisplayLookup = {
  __index = function(t, key)
    if type(key) == 'number' then
      for i,v in ipairs(rawget(t,'ranges')) do
        if key >= v[1] and key < v[2] then
          return v[3]
        end
      end
    end

    return rawget(t, key)
  end,

  new = function(self, ranges)
    local t = setmetatable({ranges = ranges}, self)

    t.OnGetDisplayValue = function(memoryrecord,valuestring)
      local n = tonumber(valuestring)
      if not n then return false end

      local s = t[n]
      if not s then return false end

      return true, valuestring .. s
    end

    return t
  end
}

local happiness = DisplayLookup:new{
  { 0, 4, ' (Angry)' },
  { 4, 7, ' (Neutral)' },
  { 7, 11, ' (Happy)' },
}

local memrec = AddressList.createMemoryRecord()
memrec.OnGetDisplayValue = happiness.OnGetDisplayValue

You can assign the `OnGetDisplayValue` property to existing memory records by using the functions `AddressList.getMemoryRecordByDescription` or `AddressList.getMemoryRecordByID`.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Coreveen
Cheater
Reputation: 0

Joined: 12 May 2011
Posts: 41

PostPosted: Wed Mar 16, 2022 3:48 am    Post subject: Reply with quote

I've modified my response since my realization. I can't double post yet so I'll write it at the bottom. Skip to the 'Edit:' below to avoid the unnecessary text.

Thank you for taking the time to try and teach me this. I'm struggling with figuring out how to get either of those code samples to work for this task.

-failure of a script snip-

I've tried all 3 on their own, and after making what I thought were the intended modifications to get it working on my table, resulting in nothing happening when I clicked Execute Script, I tried combinations between the 3. Either I get an error when I execute or nothing at all happens.

If we rewind a bit to my dumb level, I click Table -> Show Cheat Table Lua Script and paste / modify the code here, Save, then click Execute Script when it's ready.

Is that correct? If not, please let me know the correct way.

As for the exceptionally poor guesswork of the actual code I'm trying to get working, I don't exactly understand what it's going to do when I click Execute script.

Assuming I do have a well written script, when I execute, should I see the word for which mood suddenly appear on my table where my Mood dropdown record shows 0:Angry still?

What happens to a previous script I executed after I make changes and re-Execute the new script?

My apologies I'm such a scatterbrain about this. I really do want to learn it though.

---

Edit:

Alright, I really need to pay attention to the table better. The amount of lines on the table itself is extremely high so I didn't even notice the executions were inserting these sort of pre-coded records wayyyy down at the bottom of the table. That's a tad embarrassing. Very interesting. Thanks so much guys!

I'm also very pleased to see it shows both the value and the word as I'd still like to know how close or far in the range I am from a threshold for certain data. Was going to ask how to accomplish this, but it looks like it already works like that.

Now I understand why there is a record creating function. I'll work out the syntax and other language code the best I can as I diversify the data displays around the table and in future tables.

Please forgive the slowness.

@AylinCE
Your code in particular after my realization, I can't seem to get working as a Lua Executable script. It just doesn't seem to do anything, even when I modify the correct information in.

I am really not sure how I'd activate through a trainer or ASM. Most of the stuff I've done outside of simple memory searching and editing with hotkeys directly from the table, are extremely basic AOB Injections. Sometimes even just there to trigger displaying a value of the address it's assembled around.

It looks like it'd be fun to learn this right, though!

@ParkourPenguin
Both your code samples worked exactly as I'd hoped for! I especially appreciate the simplicity of the shorter one while you also included a more advanced one that achieves the same goal. This answers and asks many questions. Again, thank you very much!

Edit 2:
Turns out the working scripts don't seem to stick after saving the table, closing both it and the game and then re-opening both and attaching.

Edit 3:
Yeah, I have no idea what I'm doing.

--local memrec = AddressList.createMemoryRecord()
local memrec = AddressList.getMemoryRecordByDescription('Mood')
memrec.OnGetDisplayValue = happiness.OnGetDisplayValue

Throws an undefined Lua error:

Error:[string "local DisplayLookup = {
..."]:40: attempt to index a nil value (local 'memrec')

Is it that I have multiple entities with a Mood stat listed?

Back to the drawing board...
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4709

PostPosted: Wed Mar 16, 2022 11:39 am    Post subject: Reply with quote

Coreveen wrote:
Turns out the working scripts don't seem to stick after saving the table, closing both it and the game and then re-opening both and attaching.
That's correct. Certain properties don't get saved along with the table- a memory record's OnGetDisplayValue property is one of those. You'll need to initialize the memory records again every time you open the script.

Coreveen wrote:
Yeah, I have no idea what I'm doing.

Code:
--local memrec = AddressList.createMemoryRecord()
local memrec = AddressList.getMemoryRecordByDescription('Mood')
memrec.OnGetDisplayValue = happiness.OnGetDisplayValue
Throws an undefined Lua error:
Code:
Error:[string "local DisplayLookup = {
..."]:40: attempt to index a nil value (local 'memrec')

If getMemoryRecordByDescription returns nil, then no memory record exists with that description. This needs to be an exact match: substrings aren't considered.
If multiple records exist, then it will return the first one it finds.

Depending on how you have your table laid out, you could loop through child records.
This is an example you can play around with a little if you start and attach to the CE tutorial:
Code:
local DisplayLookup = {
  -- omitted: same as before
}


-- this just generates an example table: you can mostly ignore this function
-- attach to some process (e.g. CE tutorial) to get some memory
function generate_records()
  local header = AddressList.getMemoryRecordByDescription'Example Characters'
  if header then
    header.destroy()
  end
  local aa_result, err = autoAssemble'globalalloc(foo,4096)'
  if not aa_result then
    print'Warning: could not allocate memory. Attach to a process to write to values.'
    print(err)
  end
  header = AddressList.createMemoryRecord()
  header.Description = 'Example Characters'
  header.IsAddressGroupHeader = true
  header.Address = 'foo'
  header.Options = '[moHideChildren]'

  for i = 1, 5 do
    local character = AddressList.createMemoryRecord()
    character.Description = 'Character '..i
    character.IsAddressGroupHeader = true
    character.Address = ('foo+%x'):format((i-1)*0x100)
    character.Options = '[moHideChildren]'
    character.appendToEntry(header)

    local status = AddressList.createMemoryRecord()
    status.Description = 'Status'
    status.Address = ('foo+%x'):format((i-1)*0x100+0xC)
    status.Type = vtDword
    if aa_result then
      status.Value = tostring(i * 2)
    end
    status.appendToEntry(character)

    local health = AddressList.createMemoryRecord()
    health.Description = 'Health'
    health.Address = ('foo+%x'):format((i-1)*0x100+0x24)
    health.Type = vtSingle
    if aa_result then
      health.Value = tostring(math.random() * 100)
    end
    health.appendToEntry(character)
  end
end
generate_records()

local happiness = DisplayLookup:new{
  { 0, 4, ' (Angry)' },
  { 4, 7, ' (Neutral)' },
  { 7, 11, ' (Happy)' },
}

local health = DisplayLookup:new{
  { 0, 10, ' (Dying)' },
  { 10, 50, ' (Bad)' },
  { 50, 80, ' (OK)' },
  { 80, 101, ' (Good)' },
}

-- maps memoryrecord descriptions to the above lookups
-- i.e. `'Status', 'Health' -> happiness, health` respectively
local memrec_description_to_lookup = {
  Status = happiness,
  Health = health,
}

-- initializes OnGetDisplayValue properties of memory records
function init_OnGetDisplayValue()
  local header = AddressList.getMemoryRecordByDescription'Example Characters'
  assert(header, '"Example Characters" memory record does not exist')

  for i = 0, header.Count - 1, 1 do
    local character = header.Child[i]
    for j = 0, character.Count - 1, 1 do
      local memrec = character.Child[j]
      local lookup = memrec_description_to_lookup[memrec.Description]
      if lookup then
        memrec.OnGetDisplayValue = lookup.OnGetDisplayValue
      end
    end
  end
end
init_OnGetDisplayValue()

There are plenty of Lua tutorials out there if you want to learn more about the Lua language itself: stuff like for loops and Lua tables (i.e. {}). All the functions relating to memory records and other stuff are things CE added to Lua to let you interact with CE.
See the file celua.txt in the main CE directory for documentation on Lua functions- particularly for the MemoryRecord Class.
There is also likely information on the CE wiki and examples you can find by searching for functions.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Coreveen
Cheater
Reputation: 0

Joined: 12 May 2011
Posts: 41

PostPosted: Wed Mar 16, 2022 10:36 pm    Post subject: Reply with quote

@ParkourPenguin

Thanks again for helping make more sense of this.

So I'm still trying to get the other code working, for now I'll reserve playing with the new code once I've got this figured out and working.

-snip obsolete text-

Now I'm trying to add upon it by using it on another record at the same time and it is throwing errors.

-snip obsolete text-

Edit:
Alright it seems that it just doesn't like my methodology for testing script changes. So how I've been running new tests is simply copy/pasting the addresses that were affected by the script, and deleting the original records so they 'lost' their display value on the table. Then I'd try to click execute again and it would throw an error.

Renaming the records without actually changing them (double click + enter) seems to reset them to have them detected again by a script execution. How bizarre. This realization also lets me revert back to my organized child branching ways, which I like.

Edit 2:
Alright, I moved on to your new code to play around with. I opened the CE Tutorial, attached a new instance of CE to it and executed the code. It threw an error:

Code:
Error:[string "local DisplayLookup = {
..."]:53: attempt to call a nil value (method 'new')


But it also added Example Character (address: foo) along with 5 children records from foo with various offsets. Each of these children have a health and status record with values.

First question is, is there error intended?

Second is, how can I get it to generate specific multi level pointers? Or simply use an already existing address.

Third is, can other CE functionality be generated in this manner alongside them, such as add color to the record, making it a dropdown display, dealing with hotkeys, displaying the value as hex or decimal and other things like this?

And an unrelated question, when records start repeating, such as 5 entities that each have a Mood address, how would one append display values to all of them? Would I use the get record by ID function instead? How does one obtain the ID of a memory record for this purpose?

I realize these questions probably make me look incredibly dumb, but learning isn't exactly my greatest strength. Apologies for this again, and thanks for your time.

Edit 3:
It also appears that not all of the code is being executed as intended. I see some display value sorcery that's supposed to happen, but it isn't.

The table simply shows the standard values that the generating for loop arithmetically initially generated with them.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4709

PostPosted: Thu Mar 17, 2022 1:30 am    Post subject: Reply with quote

Coreveen wrote:
Alright, I moved on to your new code to play around with. I opened the CE Tutorial, attached a new instance of CE to it and executed the code. It threw an error:
Code:
Error:[string "local DisplayLookup = {
..."]:53: attempt to call a nil value (method 'new')
...
First question is, is there error intended?
I intended for you to read the code I posted. Specifically the first 3 lines:
Code:
local DisplayLookup = {
  -- omitted: same as before
}
Omitting code that's the same as before is just to keep the post length down. Copy/paste it from my post before that.

Coreveen wrote:
Second is, how can I get it to generate specific multi level pointers? Or simply use an already existing address.
You shouldn't need to generate new memory records every time you open the table. Just assign to the relevant memory records' OnGetDisplayValue properties.
I can't tell you exactly how to assign to already existing memory records because I don't know how your table is laid out. That's what my previous post was for: it shows you an example of looping through memory records that already exist. The function that generates the memory records is just a convenience so that you don't have to do that yourself, hence the comment:
Code:
-- this just generates an example table: you can mostly ignore this function


Coreveen wrote:
How does one obtain the ID of a memory record for this purpose?
I don't know of any easy way of doing it. I'd just use Lua to print the value of the ID if I really needed it. e.g.:
Code:
print(AddressList[0].ID)
I've seen other tables use IDs before, but I haven't used them myself.

Coreveen wrote:
learning isn't exactly my greatest strength.
Learning a new programming language takes a significant amount of time and effort, especially if you're trying to learn an API along with it.
_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Coreveen
Cheater
Reputation: 0

Joined: 12 May 2011
Posts: 41

PostPosted: Thu Mar 17, 2022 5:07 am    Post subject: Reply with quote

@ParkourPenguin
I did read the code, but didn't necessarily understand it on the first pass. I had my suspicions but wasn't entirely sure on the purpose or the intended effect upon execution - so I ask questions to confirm and clarify. Apologies if that's on the annoying side.

Okay, so generating entire tables from a Lua script doesn't sound like a normal thing or even a recommended thing. I was kind of hoping for an answer like that.

Does print show the information only in that same window as caught exceptions or is there some other place it prints that I'm unaware of?

Is special formatting possible from Lua like adding color or hotkeys to the records and such?

As for learning a new programming language.. well.. The only real programming experience I have is making some server plugins for (Minecraft) Bukkit. I more or less was able to decipher and emulate already existing things I'd seen demonstrated through decompiling or open source where I could see the actual effects taking place on the game server, but to call that actually learning Java programming instead of understanding a handful of knowledge for that specific game server's API would be a joke. Writing code for it from scratch was basically out of the question as I never really took the time to learn the entire language from the basics.

That said, I did spend around 5 or 6 hours yesterday studying various YouTube videos learning about the assembly language and how it gets used with CE.

A lot of common examples I've seen used in CE auto assembler scripts over the years I didn't understand how they really worked at all, but now I'm getting pretty comfortable in my understanding of the basic fundamentals so far. Though I'm sure it will be one of those things I'll always be learning more about as I go. I'm very interested in learning Lua but I'm frankly extremely intimidated and overwhelmed by the prospect.

Sorry about the lengthiness of the posts.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4709

PostPosted: Thu Mar 17, 2022 11:02 am    Post subject: Reply with quote

Yes, most properties of memory records are exposed to Lua. If you look in celua.txt:
Code:
MemoryRecord Class:
  ...
  Color: integer
  ShowAsHex: boolean - Self explanatory
  ShowAsSigned: boolean - Self explanatory
  ...
  HotkeyCount: integer - Number of hotkeys attached to this memory record
  Hotkey[] : Array to index the hotkeys
  ...
  createHotkey({keys}, action, value OPTIONAL, description OPTIONAL): Returns a hotkey object
  ...
Note that these hotkeys are instances of the MemoryRecordHotkey class, not the GenericHotkey class (created w/ createHotkey function).

And again, my personal opinion is that it's easier to make the table yourself first and then apply Lua events (e.g. OnGetDisplayValue) to the relevant memory records as needed. Generating an entire table from scratch just because you don't know how to access memory records that already exist seems ridiculous.

Just to be clear, the "programming language" I was talking about you learning was Lua. Lua itself isn't hard to learn. It's the CE API that does weird things that aren't really documented anywhere. The best way to learn it is to read code written by someone who (mostly) knows what they're doing, contrast that with existing documentation (i.e. celua.txt), and extrapolate that information to other documented items.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites