Jump to content

Codex

Members
  • Posts

    13
  • Joined

  • Last visited

  • Days Won

    2

Codex last won the day on December 16 2016

Codex had the most liked content!

Contact Methods

  • Website URL
    https://www.paypal.me/ArthurCasey

Profile Information

  • Gender
    Male
  • Location
    NJ

Previous Fields

  • Favorite pizza topping
    cheese
  • Why do you want to join DarkMatters?
    for the mods
  • All time best video game ever played
    Zelda
  • Real Name
    Arthur
  • Country
    United States

Recent Profile Visitors

1,618 profile views

Codex's Achievements

Indium Shaman

Indium Shaman (4/20)

10

Reputation

  1. CRC errors are not ram related, they are hard drive related, if you are getting them then you may have bad sectors on your hard drive. Try running CHKDSK utility to isolate these sectors. http://www.wikihow.com/Fix-a-Cyclic-Redundancy-Check-Error
  2. When you write a program/script you are testing the possible outcomes whether they are for the benefit of your idea or the exclusion of things you don't want. So you should always have the thought in the back of your mind (especially if the code is meant for production) of "What if?". This what if? mindset is what seperates good code from really bad code, all code is written in steps, and 99% of it never works the 1st time around, plus your code is always evolving so its ok to write something out in a complicated manner and then go back later on and shorten it up or add to it. On a final note, if you are satisfied with the layout and execution of your code... then you are missing or overlooked something.. Good programmers are never satisfied with their code... hell we will spend days working on a small fragment of code til we figure out why the hell it isn't working.. But that is how you become a good coder is learning from your mistakes.. and you will make a lot of them I am sure this tutorial could of been better, but I don't really have a lot of time to devote to expanding it. For further reading please check out. https://www.lua.org/manual/5.1/ or https://www.tutorialspoint.com/lua/index.htm
  3. Functions and Scope A function in any programming language is created and used to simplify redundant coding, the basic form of a function body is constructed as: function myFunction() end To construct or define a function we start with the keyword function followed by the name of the function, a both open and closed parentheses and the end keyword to close the function. Functions can also be declared/defined like this. myFunction = function() end You can also rename a function by passing the function to another identifier. function myFunction(value) print(value) end myNewFunction = myFunction myNewFunction(10) -- prints 10 The value identifier in the parentheses of myFunction is arbitrary and can be named anything, this identifier is known as a parameter, it is used to pass information to the function so that the function can do what it needs to do with that data. Lets say we wanted to calculate the conversion of fahrenheit to celsius and vice versa we could create a function to calculate those values for us. function convertTemperature(temperature, toCelsius) local value = "The temperature ".. temperature .. " in " if toCelsius then value = value .. "fahrenheit is "..(((temperature - 32) * 5) / 9) .. " in celsius." else value = value .. "celsius is "..(((temperature * 9) / 5) + 32) .. " in fahrenheit." end print(value) end Now we can call on the function to determine what the temperature of say 23 fahrenheit is in celsius. convertTemperature(23, true) -- prints The temperature 23 in fahrenheit is -5 in celsius. Now if we wanted to determine what the value of say 0 celsius is in fahrenheit we could simply set the 2nd parameter to false or just omit it entirely. convertTemperature(0) -- prints The temperature 0 in celsius is 32 in fahrenheit. Scope Scope refers to the visibility of variables, functions or tables. In other words, which parts of your program can see or use them. There are two forms of scope Global & Local. Local variables are created with the local keyword, their scope or visibility only exist within the body it was declared in where as global is simply defined without using the local keyword and its visibility is seen outside the body it was declared in but only when that body is brought into view. Lets look at an example of both local and global scope. function A() -- x is global, but only global within the scope of function A x = 1 end function B() -- since we never called on the function A, x returns nil, because it doesn't exist outside of A print(x) end B() -- prints nil As you can see from the comments above, the scope of x defined in A is global to A, but when called by B its looses its scope because we never brought A inside of the scope of B. Lets try this again but this time calling A inside of B. function A() -- x is global, but only to the scope of function A x = 1 end function B() A() -- call function A and bring its values which are global into function B's scope print(x) end B() -- prints 1 Now that we have called function A within function B, B can now clearly see the value of x. So what if we changed x's scope to local, would B still see the x when we called A from B? Well lets try it. function A() local x = 1 end function B() A() print(x) end B() -- prints nil The answer is no, because the scope of x was declared local to the function of A, so even tho function B called on A, any values which were not declared as global B won't be able to see. Here is where it might get a little confusing (If you aren't confused already ). When a value is declared as local outside of a function then its scope although declared local is actually global. You are probably asking yourself, what do you mean "When a value is declared as local outside of a function then its scope although declared local is actually global?" Well lets take a look at an example: local text = "I am text, although I am declared local, I am actually global to most things" function test() print(text) end test() -- prints I am text, although I am declared local, I am actually global to most things The reason the test function can see text is because text was declared before test, allowing test to access text's value. If we were to declare text's value after test, it would print nil when we called it. function test() print(text) end local text = "I am text, although I am declared local, I am actually global to most things" test() -- prints nil So now you might be asking yourself, "What if I omit the local keyword from text, will I be able to access text's value?". Lets have a look. function test() print(text) end text = "I am text" test() -- prints I am text Sure enough you can access text's value from test, even tho test was defined before text, this is because the lua interpreter isn't actually calling the value of text when the function test is defined, it only looks for the value of text when the function test is called. Returning Values We have covered quite a bit in relation to functions, we've learned how to construct and define a function, pass information to a function, we learned about scope and even learned how to print values to the console. But there is more to functions than just printing values, such as returning them to whatever called the function. To return a value from a function is pretty straight forward, in order to this we use the return keyword. function add(a, b) return a + b end The add function could be called like this. function add(a, b) return a + b end local sum = add(6, 7) print(sum) -- prints 13 Functions can also return not just single values but they can also return true/false, tables, multiple values or even other functions. Here is an example (although it could be written a lot better ) of a function calling other functions but returning either a string or a table of values. --[[ if the strings length is greater 2 this will treat a string as an array and pop off the 1st 2 characters of the string returning the remaining string, if not it returns nil ( nil essentially means false ) ]] function pop(v) return #v > 2 and v:sub(3, #v) or nil end -- this function will clip the string for the 1st 2 characters and return them as a table function clip(j) local y = {} for I = 1, #j do table.insert(y, j:sub(I, I)) end return y end --[[ this function will convert hex color codes to its respective rgb values optionally returning a string or table of values ]] function hexToRgb(hexColor, asString) -- all possible hexidecimal values local hex = { ['0'] = 0, ['1'] = 1, ['2'] = 2, ['3'] = 3, ['4'] = 4, ['5'] = 5, ['6'] = 6, ['7'] = 7, ['8'] = 8, ['9'] = 9, ['a'] = 10, ['b'] = 11, ['c'] = 12, ['d'] = 13, ['e'] = 14, ['f'] = 15 } -- table to hold the rgb color codes local rgb = {} -- loop while hexColor does not equal nil while(hexColor) do local value = clip(hexColor:sub(1, 2):lower()) table.insert(rgb, ((hex[value[1]] * 16) + hex[value[2]])) hexColor = pop(hexColor) end return asString and table.concat(rgb, ", ") or rgb end print(hexToRgb('FF2344', true)) -- prints 255, 35, 68 Admitingly the above code could be written a lot better, with type checking and such... so lets do that now, lets re-write the above code to handle different types of values with the appropriate lengths. -- all possible hexidecimal values local hex = { ['0'] = 0, ['1'] = 1, ['2'] = 2, ['3'] = 3, ['4'] = 4, ['5'] = 5, ['6'] = 6, ['7'] = 7, ['8'] = 8, ['9'] = 9, ['a'] = 10, ['b'] = 11, ['c'] = 12, ['d'] = 13, ['e'] = 14, ['f'] = 15 } --[[ if the strings length is greater 2 this will treat a string as an array and pop off the 1st 2 characters of the string returning the remaining string, if not it returns nil ( nil essentially means false ) ]] function pop(v) return #v > 2 and v:sub(3, #v) or nil end -- this function will clip the string for the 1st 2 characters and return them as a table function clip(j) local y = {} for I = 1, #j do table.insert(y, j:sub(I, I)) end return y end --[[ this function will convert hex color codes to its respective rgb values optionally returning a string or table of values ]] function hexToRgb(hexColor, asString) -- table to hold the rgb color codes local rgb = {} -- determine what type of data hexColor is if type(hexColor) == "string" then while(hexColor and #hexColor > 1) do local value = clip(hexColor:sub(1, 2):lower()) table.insert(rgb, ((hex[value[1]] * 16) + hex[value[2]])) hexColor = pop(hexColor) end return (#rgb > 0) and (asString and table.concat(rgb, ", ") or rgb) or "You must use at least 2 values" else -- this will handle all other types of data which we try to pass to this function return "This function will not process " .. type(hexColor) .. "s, please place your values in single(\') or double quotes(\")" end end So now lets test that theory. Can this semi-rewritten function handle different values types and proper lengths? Lets try it passing limited values print(hexToRgb('B', true)) -- prints You must use at least 2 values Now lets try passing it just numbers print(hexToRgb(00, true)) -- prints This function will not process numbers, please place your values in single(') or double quotes(") Now lets try with a table, empty or otherwise. print(hexToRgb({}, true)) -- prints This function will not process tables, please place your values in single(') or double quotes(") Next lets try with a function, in this case an anonymos one. print(hexToRgb(function() end, true)) -- prints This function will not process functions, please place your values in single(') or double quotes(") Lets pass it a nil value (literally) print(hexToRgb(nil, true)) -- prints This function will not process nils, please place your values in single(') or double quotes(") So... As you can see the function can now handle different values thrown at it ( still not perfect but who/what is ).
  4. Iterators There are 4 types of iterators aka loops in lua, the numerical for, the generic for, the while and the repeat. Lets take a close look at each one. The Numerical For for variable = start, stop, step do -- code goes here end The numerical for loop consists of the keyword for, variable is simply the local variable associated with the for loop and can be named almost anything, I know there is that word local again . Then we have the assignment operator which takes the value stored in start and stores it in variable. Start is merely a description of the execution of the for loop, start is a value of where we would like our for loop to start counting, e.g. for I = 1. Stop is a value which would like our for loop to stop at (e.g. for I = 1, 10) and finally Step is the incremental value for our local variable, if omitted the the for loop uses step's default value of 1. Lets take a look at an example of the numerical for loop so maybe it will make more sense. -- 1st example, with the step value omitted for I = 1, 5 do print(I) end -- prints 1 2 3 4 5 -- 2nd example, with a step value of 2 for I = 1, 10, 2 do print(I) end -- prints 1 3 5 7 9 In the 1st example the numeric for loop prints the value of I 5 times, by omitting the step value the for loop used the default step value of 1 and printed every iteration of I to screen. In the 2nd example the for loop does pretty much everything as the 1st example did except that we manipulated the I's value based on the step value. Using 2 as our step value we tricked the for loop into increasing the value of I by 2 rather than 1 per iteration this is why the results of I are 1,3,5,7,9 rather than 1,2,3,4,5,6,7,8,9,10, because we are adding the step value to I per iteration. Using this formula per iteration for step being 2. I = 1 step = 2 max = 10 -- compare I to max -- iteration 1 print(I) -- 1 I = (I + step) -- compare I to max -- iteration 2 print(I) -- 3 I = (I + step) -- compare I to max -- iteration 3 print(I) -- 5 I = (I + step) -- compare I to max -- iteration 4 -- etc... So how does the numeric for loop know when to stop? Simple it initially evaluates all 3 expressions, the value of I, the max value to meet and the step value if any And then compares the value of I to the max value to meet based on the step value.. this sounds confusing I bet We might need another example to show what I am referring to when I say based on the step value. -- 1st example for I = 5, 1, -1 do print(I) end -- prints 5 4 3 2 1 -- 2nd example for I = 10, 1, -2 do print(I) end -- prints 10 8 6 4 2 In the 1st example we are using a negative number (-1) as our step value and assigning I a value of 10 while making the max value to meet 1 Since the step value + I controls the value to increment per iteration we can still use this same formula as we did for a positive step value Using this formula per iteration for step being -1. I = 10 step = -1 max = 1 -- compare I to max -- iteration 1 print(I) -- 10 I = (I + step) -- compare I to max -- iteration 2 print(I) -- 9 I = (I + step) -- compare I to max -- iteration 3 print(I) -- 8 I = (I + step) -- compare I to max -- iteration 4 -- etc... Using this formula per iteration for step being -2 I = 10 step = -2 max = 1 -- compare I to max -- iteration 1 print(I) -- 10 I = (I + step) -- compare I to max -- iteration 2 print(I) -- 8 I = (I + step) -- compare I to max -- iteration 3 print(I) -- 6 I = (I + step) -- compare I to max -- iteration 4 -- etc... If we add a negative number to a positive number we are essentially subtracting e.g. 10 + (-2) = 8 The Generic For The generic for loop is always used on a table, it is define as for key, value in pairs(table_name) do -- code goes here end -- or for key, value in ipairs(table_name) do -- code goes here end What a generic for loop does it allows us to easily traverse through a table. Early on we referred to tables having properties and indexes well the index of a table can be referred to as its key and a property as its value. Lets break apart the generic for loop and explain how it works. The generic for loop is initialized using the for keyword (just as you did with the numeric for), it is then assigned a variable to be used to hold the table's key value this variable can be named anything even an underscore ( _ ) as long as it follows lua's naming convention. We then place a comma after the key's variable name and create another variable this variable will hold the value of the table's key. We then place a space and type the in keyword and then another space and use either pairs or ipairs followed by an open parentheses followed by the table name followed by a closing parentheses and then another space followed by the do keyword and the end keyword to close the generic for loop. The difference between pairs and ipairs is pairs will iterate over everything in the table regardless if it has a numerical key or not in no particular order. Where as ipairs will only iterate through a table if the table has keys that are numerical. Lets take a look at both pairs & ipairs to see how they are different. Using pairs local t = { ["one"] = 1, [2] = 23, codex = "my name", 50 } for k, v in pairs(t) do print(k, v) end -- output 1 50 one 1 2 23 codex my name Using ipairs local t = { ["one"] = 1, [2] = 23, codex = "my name", 50 } for k, v in ipairs(t) do print(k, v) end -- output 1 50 2 23 As you can see from the 2 examples pairs printed everything to the screen where as ipairs only printed non-text based keys. While loop The while loop although hardly ever used in most scripts (at least in my experience), has a simple structure. while(condition) do -- code to execute here end As long as the condition of the while loop returns true the while loop will execute. Here is an example of a while loop: local I = 1 while(I < 10) do I = I + 1 print(I) end -- prints 2 3 4 5 6 7 8 9 10 Repeat Until loop The repeat until loop has a similar structure to the while loop. repeat -- code to execute goes here until (condition) Here is an example of the repeat until loop: local I = 1 repeat I = I + 1 print(I) until I > 10 -- prints 2 3 4 5 6 7 8 9 10 11 I rarely if ever use the while/repeat loops for anything in lua due to the fact that they can cause an infinite loop and crash a program.
  5. Operators Its important that we cover the different type operators which are available to us in lua (and many other languages) ‚ÄčArithmetic Operators + The plus sign is the addition operator it is used to add 2 operands together. Example: (2 + 2) = 4 - The hyphen is the minus operator it has 2 purposes 1 of which can negate a value (-2) (aka the urinary operator) and the other subtracts 2 operands. Example: (2 - 2) = 0 / The forward slash is the division operator, it is used to divide 2 operands. Example: (2 / 2) = 1 * The asterisk is known as the multiplication operator it is used to multiply 2 operands. Example: (2 * 2) = 4 % The percentage sign is known as the modulo operator, its purpose is a 2 step process, 1st it divides 2 operands and then returns the remainder of what is left over. Example: (3 % 2) = 1 ^ The caret is called the exponent operator, it takes 2 operands and returns the exponent of Example: (2 ^ 3) = 8 Relational Operators The relational operators return true or false based on the outcome of their comparison. == Two equal signs is known as the equivalence operator, it is used to check whether 2 operands are equal or not ~= The tilde and the equal sign is known as the not equal to operator, it essentially checks whether the 2 operands are not equal to one another. > The greater than checks to see if the value on the left is greater than the value on the right. < The less than checks to see if the value on the left is less then the value on the right. >= The greater than or equal to is used to check if the value on the left is greater than or equal to the value on the right. <= The less than or equal to checks to see if the value on the left is less than or equal to the value on the right. Logical Operators The logical operators also return true or false based on the outcome of their comparison. and The and logical operator checks to see if both operands are true, if they both are true, then a value of true is returned. Example: (1 == 1 and 2 == 1) -- returns false or The or logical operator checks to see if either the left or the right operand is true, if either is true then it returns a value of true. Example: (1 == 1 or 2 == 1) -- returns true not The not logical operator returns the opposite of the condition, if the condition is true not makes it false and vice versa. Example: ( not true) -- returns false Miscellaneous .. The 2 dots are used in concatenation. Example: print("hello" .. " world!") -- prints hello world! # The hash tag is known as the unary which returns the length of a string or table. Example: print(#"hello world!") -- prints 12 Example: print(#{1, 2, 3}) -- prints 3 The Order of Precedence Although in programming you can use parentheses to explicitly direct the order execution of an expression its still important to learn the order of precedence. Unary not # - (right to left) Concatenation .. (right to left) Multiplicative * / % (left to right) Additive + - (left to right) Relational < > <= >= == ~= (left to right) Equality == ~= (left to right) Logical AND and (left to right) Logical OR or (left to right) Control Structures A control structure is simply a logical operation which is used to control the flow of execution. Here is an example of a simple control structure. if a > b then print("a is greater than b") elseif a < b then print("b is greater than a") else print("both a and b are equal in value.") end The above code states, if a is greater than b then print a is greater than b. Else if b is greater than a print b is greater then a, else print both a and b are equal in value. Another way we can use a control structure is through short hand, using the logical operators to assign values to a table or variable. Example: -- if the player level is greater than 100 (and) assign 50 to experience -- else (or) assign 200 to experience local experience = (playerLevel > 100) and 50 or 200 The short hand assignment can be nested, I'll expand more on this at a later time. If you are familiar with c++ or even php you've already used shorthand notation using ? and : In php or c/c++ the and/or short hand is very much similar to // php $experience = ($playerLevel > 100) ? 50 : 200; // c/c++ int experience = (playerLevel > 100) ? 50 : 200;
  6. The goal of this thread, to provide you the reader with a basic foundation in the lua scripting language. Which is essentially the supporting language for almost every file in the scripts directory. This guide will not cover command line lua, if you use windows as I do then I recommend installing https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/luaforwindows/LuaForWindows_v5.1.4-46.exe Comments, Naming Convention and Structure Comments in every programming language give the programmer and the non-programmers a general idea of what is going on in the code, especially when that code becomes excessively large and or complex. There are 2 types of comments in lua Single Line Comment: -- This is a single line comment, everything til the end of the line will be commented out & ignored by the lua interpreter Multi-Line Comment: --[[ This is a multi-line comment, everything that is contained within the --[[ ]] is ignored by the lua interpreter ]] Technically speaking there is an unwritten 3rd type of comment in every language, which is called the naming convention although a naming convention falls under a consistent style of program (e.g. nameOfPlayer, name_of_player etc..) it can also be used as a comment style of programming, lets look at an example. local s, x = 18000, { p = 0.50, f = 0.10} What the heck is s, x, p & f? Nevermind what the values they hold but what are s, x, p & f used for? It is not very clear and it would take a bit time to go through the code to see what these things are used for. So lets rename these letters so that they describe their purpose. local storage, xpAdd = 18000, { bronze = 5, silver = 10} Now we have a general idea of what these things will be used for even if we aren't a programmer. Structure is also an important part of readability it allows us to see the level of execution, find bugs and make our less then savy code seem a bit sexy When we talk about structure we are referring to proper spacing & indentation of the code. local config = { xpAdd = { bronze = 5, silver = 10 }, storage = 18000 } Variables A variable is simply a container used to hold a value, think of a variable as a box where you can only hold 1 thing at a time in that box. A variable must start with a letter or underscore and can be 1 character to the entire alphabet in length, variables can also contain numbers, letters or underscores but absolutely no spaces, variables are case sensative meaning wow, WoW & wOw are all different variables. The way we declare a variable is by typing the variable's name followed by an equals sign ( = ) and the value you want to store in the variable, the equal sign is known as the assignment operator. local myVariable = 5 -- a variable with a default value of 5 The reason it is called the assignment operator is because we are taking the thing on the right and assigning it to the thing on the left. Tables A table is similar to a variable but instead of just holding 1 value it can hold multiple values & even other tables. The basic definition of a table is : local myTable = {} -- this is an empty table Tables can also be assigned properties at any time, either during its declaration or as we progress through the script. local myTable = { name = 'Codex' } The tables property value can then be accessed by simply using the name of the table followed by the dot operator ( . ) and then the property's name local myName = myTable.name -- assign the value stored in myTable.name to myName Tables can also be assigned a property based on its index value, think of a table as a bookshelf and its index value as one of its shelves. Let's create a new table. local myNewEmptyTable = {} And assign it a value of 10 at its 1st index, unlike other language lua's index by default starts at 1. myNewEmptyTable[1] = 10 This also could have been applied like this myNewEmptyTable[#myNewEmptyTable + 1] = 10 Or even this table.insert(myNewEmptyTable, 1, 10) Although the index value of a table normally starts with 1, you can force lua to start the index at 0 or any index you'd like simply by writing. local table_ = { [0] = 23, -- index 0 27, -- index 1 89 -- index 2 } local table_ = { [0] = 23, -- index 0 [5] = 27, -- index 5 [100] = 89 -- index 100 } Tables can also be assigned tables as properties. It is important to note that if you have more than 1 property in a table you must place a comma ( , ) prior to the last property listed. Example: local myNewEmptyTable = { 10, -- index 1 innerEmptyTable = {} -- index 2 } Lets say you wanted to add a property with a value to the innerEmptyTable of myNewEmptyTable, you would simple call myNewEmptyTable followed by the dot operator followed by the property innerEmptyTable followed by the dot operator followed by the new property name followed by the assignment operator followed by the value. Example: myNewEmptyTable.innerEmptyTable.someProperty = 34 To access the value stored in someProperty of the nested tables you call the nested tables just as you did above except omitting the assignment operator and the value. local x = myNewEmptyTable.innerEmptyTable.someProperty If tables have property names then they can be accessed either using the dot operator (table.property) or by using the the name of the property enclosed in single or double quotes (known as a string) enclosed in square brackets (known as a string index). Example: -- Using the dot operator ( . ) local x = myNewEmptyTable.innerEmptyTable.someProperty -- Using a string index local x = myNewEmptyTable['innerEmptyTable'].someProperty -- or local x = myNewEmptyTable['innerEmptyTable']['someProperty'] -- or local x = myNewEmptyTable.innerEmptyTable['someProperty'] Tables can also be assigned tables as indexes local myTable = { [{1,2}] = "hi there", [{3, 4, 7, 10}] = "weird eh?" } We won't go into how to access table's with table indexes for now until we cover functions a bit later. Tables can also be assigned tables with no property names. local tableOfTables = { {2, 4, 6}, -- index 1 {1, 3, 9}, -- index 2 {5, 8, 7} -- index 3 } Lets say we wanted to access the value of 9 from tableOfTables, we would use its table index value followed by that tables index. Example: local x = tableOfTables[2][3] -- this will store the value of 9 in x Anytime you see text enclosed in double ("") or single ('') quotes this type of data is known as a string, a string can be 1 character like "A" or can be many characters like "Hi my name is Codex :)" A table can also use a string as a property name in lua but it must be surrounded by single / double quotes and surrounded by square brackets ( [] ). Example: local myStringTable = { ['a short sentence with spaces :)'] = 56 } print(myStringTable['a short sentence with spaces :)']) -- prints 56 to the console Multiple Declarations Both tables and variables can be declared on the same line simply by using a comma ( , ) after each table or variable, the assigned values of each type (variable or table) must be assigned their values in the order they are declared. Example: -- Just tables local myTable1, myTable2, myTable3 = {}, {}, {} -- Just variables local myVar1, myVar2, myVar3 = 1, 'B', "some text" -- Both tables and variables local myVar, myTable = 33, {} Although we have not covered functions just yet, I wanted to exhaust the possibilities of tables. Tables can also be assigned properties which are functions. Example: local myTable = { [1] = function(x) print(x) end } The way we would execute our table's function is simply by calling the table name followed by its index or if it has a property name followed by an open and closed parentheses () and any argument(s) which we want to pass to the table's function's parameter(s). In this case our table's function does have a parameter labeled x (more on this later). print( myTable[1](10) ) -- prints 10 So far we have seen this word local used quite often through out the start of this tutorial, we will not explain its significance just yet, not until we cover functions.
  7. This thread is completely pointless...
  8. I went in the console and typed SYS EXPORTSECTORMAPS and this popped up.
  9. Progress so far, if you add the -console in the shortcut to the target. Then while at any point in the game you hit tilde (~) key and a persistent window will overlap the screen, then type help, that is as far as I've gotten so far Currently I am running one of the dll's (s2logic.dll) through a debugger. This is how I came to the conclusion that the game might have a debug window. Initially I did a search for et_duration_sec in notepad++ in txt, exe & dll file types, which lead me to this dll, then I opened it up in x64dbg and did a search for all related strings.
  10. So for instance if I were to create a test function, labeled testFunction. function testFunction() return (6000 * 60 * 24) end Then call it from within entry1, it will execute and return a value of 86400, which will then be applied to the duration value for the spell. entry1 = {"et_duration_sec", testFunction(), 25, 0, 8 }, Creating a structure in this fashion allows us to consolidate but also easily manage or update the code. The way lua works is that the code is evaluated way before it is sent to whatever called the document, this means that we can write code which manipulates the values prior to sending it to the application. (hopefully that makes sense)
  11. Some where down the road all of these values can be simplified, in that functions can be created to automatically execute these values so we won't have to search for them all. I've completely re-written game server frameworks to do just that, lua is pretty flexible and easy to work with.
  12. I intend to break down each field so that either myself or another member can build a tool which will allow you to automatically update the spells as needed. For instance in the above example: entry0 = {"et_self_shapeshift", 1000, 1995, 0, 41 }, 1995 refers to the creatures id, just using notepad++ I searched the entire spells document for that value where it only found 1 occurrence to the value. This means that its a unique id which only applies to this spell. So I did a directory search on the value 1995 and found in creatures.txt amongst other places, more data in relation to the spell. mgr.createCreature { id = 1995, itemtype_id = 12484, name = "spell_dm_berserker_shapeshift", behaviour = "Invalid", dangerclass = 7, groupmaxcount = 1, elite_creature_id = 1995, probabilityforelite = 0.000000, rank = 0, tenergy_creature_id = 1995, livesremaining = 0, unconscioustime = 20, palettebits = "1111111111111111", monstertype = 0, faction_id = 1, modelscale = 1.000000, rise_from_ground = 0, has_corpse = 1, has_soul = 1, can_strafe = 0, } It could just be a coincidence but spell_dm_berserker_shapeshift does seem to relate to the original spell. Next if I take the itemtype id value found in that block of code and I do a search in the itemtype.txt, I find this. newItemType = { -- standard info renderfamily = "RENDERFAM_CREATURE", renderprio = 0, family = "FAMILY_CREATURE", subfamily = "SUBFAM_LIFE_DRAGON", classification = "CLF_DEFAULT", flags = "FLAG_HASPREVIEWIMAGE", weargroup = "WEARGROUP_INVALID", -- 3d model + animation info model0Data = { name = "models/npc/monsters/draconian/h_draconian.GR2", user = "WEARGROUP_INVALID", }, -- logic bounding box logicBox = { minx=-34.466, miny=-56.174, minz=-0.641, maxx=29.876, maxy=38.901, maxz=94.403, }, dangerclass = 0, } mgr.typeCreate(12484, newItemType); All of this data is relevant its just a matter of picking things apart to see how they relate to one another.
  13. I just discovered this game yesterday 11-27-16 and its pretty cool, I also noticed it had a script directory which eventually led me to this community. I tried all the classes, one which I enjoyed the most was Dragon Mage and this one spell called Dragon Berserk. The only bad thing about the spell is it had a long cool down which really didn't make it that useful. So I took a look at the text files in the scripts directory and noticed they are all written in lua. So I started to mess around with some of the files, given I have a background in programming, the worst that can happen is I would have to reinstall the game. So I thought I would investigate these files and see if I could reduce the cool down of this spell. As you can see from the picture below I've done just that reduced the cool down to 1 second. I've also increased the duration 86,401 seconds basically set it to infinity (for a day) The way I did this is actually quite simple, all I did was open up spells.txt and looked for the spell mgr.defineSpell( "dm_dm_berserkerform", { eiStateName = "cSpellCast", fxTypeCast = "FX_DM_MORPH_BERSERKER_C", fxTypeSpell = "FX_DM_MORPH_BERSERKER", fxTypeCastSpecial = "", duration = 10.000000, animType = "ANIM_TYPE_SM17", animTypeApproach = "", animTypeRide = "", animTypeSpecial = "ANIM_TYPE_RIDESM17-SPECIAL", causesSpellDamage = 1, tokens = { entry0 = {"et_self_shapeshift", 1000, 1995, 0, 41 }, entry1 = {"et_duration_sec", 2750, 25, 0, 8 }, entry2 = {"et_life_leech", 75, 25, 0, 9 }, entry3 = {"et_AWVW_rel", 0, 100, 0, 5 }, entry4 = {"et_charge_shapeshift", 120, 0, 0, 5 }, entry5 = {"et_weapondamage_physical", 0, 25, 0, 9 }, entry6 = {"et_charge_shapeshift", 50, 0, 1, 5 }, entry7 = {"et_addAttackspeed", 200, 0, 2, 41 }, entry8 = {"et_duration_sec", 1000, 10, 3, 8 }, entry9 = {"et_life_leech_rel", 35, 0, 4, 9 }, entry10 = {"et_charge_shapeshift", 50, 0, 5, 5 }, entry11 = {"et_addspell_blutrausch", 1000, 0, 6, 5 }, entry12 = {"et_armor_any_rel", 0, 50, 0, 41 }, entry13 = {"et_life_buff", 150, 260, 0, 9 }, entry14 = {"et_chance_surehit", 100, 2, 0, 5 }, entry15 = {"et_physical_to_magic", 250, 0, 0, 5 }, }, fightDistance = 0.000000, aspect = "EA_DM_DRAGONMAGIC", cooldown = 40.000000 soundProfile = 0, cost_level = 250, cost_base = 500, focus_skill_name = "skill_DM_dragonmagic_focus", lore_skill_name = "skill_DM_dragonmagic_lore", spellClass = "cSpellDmMorph", spellcontroltype = "eCAtype_b_boost_self", sorting_rank = 0, }) And made the changes, please note I did not remove the original values all I did was comment them out and apply the changes. mgr.defineSpell( "dm_dm_berserkerform", { eiStateName = "cSpellCast", fxTypeCast = "FX_DM_MORPH_BERSERKER_C", fxTypeSpell = "FX_DM_MORPH_BERSERKER", fxTypeCastSpecial = "", duration = 1.000000, -- 10.000000 -- the 10 seconds might just be a default value animType = "ANIM_TYPE_SM17", animTypeApproach = "", animTypeRide = "", animTypeSpecial = "ANIM_TYPE_RIDESM17-SPECIAL", causesSpellDamage = 1, tokens = { entry0 = {"et_self_shapeshift", 1000, 1995, 0, 41 }, entry1 = {"et_duration_sec", (6000 * 60 * 24), 25, 0, 8 }, -- {"et_duration_sec", 2750, 25, 0, 8 }, entry2 = {"et_life_leech", 75, 25, 0, 9 }, entry3 = {"et_AWVW_rel", 0, 100, 0, 5 }, entry4 = {"et_charge_shapeshift", 120, 0, 0, 5 }, entry5 = {"et_weapondamage_physical", 0, 25, 0, 9 }, entry6 = {"et_charge_shapeshift", 50, 0, 1, 5 }, entry7 = {"et_addAttackspeed", 200, 0, 2, 41 }, entry8 = {"et_duration_sec", 1000, 10, 3, 8 }, entry9 = {"et_life_leech_rel", 35, 0, 4, 9 }, entry10 = {"et_charge_shapeshift", 50, 0, 5, 5 }, entry11 = {"et_addspell_blutrausch", 1000, 0, 6, 5 }, entry12 = {"et_armor_any_rel", 0, 50, 0, 41 }, entry13 = {"et_life_buff", 150, 260, 0, 9 }, entry14 = {"et_chance_surehit", 100, 2, 0, 5 }, entry15 = {"et_physical_to_magic", 250, 0, 0, 5 }, }, fightDistance = 0.000000, aspect = "EA_DM_DRAGONMAGIC", cooldown = 1.000000, -- 40.000000 (cool down period) soundProfile = 0, cost_level = 1, -- 250 (cost level & cost base make up the regen) cost_base = 1, -- 500 focus_skill_name = "skill_DM_dragonmagic_focus", lore_skill_name = "skill_DM_dragonmagic_lore", spellClass = "cSpellDmMorph", spellcontroltype = "eCAtype_b_boost_self", sorting_rank = 0, })
×
×
  • Create New...
Please Sign In or Sign Up