Вы находитесь на странице: 1из 5

-----------------

Stupid LPC Tricks


-----------------
Ichthus@Swmud
This was written with the SWmud.org mudlib which is built off of the
Nightmare-III lib running on MudOS v21.7. If these tricks work on your mudlib
and driver, feel free to copy the article making sure to credit me as the
original author.

1) Array ranges - When dealing with arrays, you occasionally have to either
select everything from the beginning to a certain point or everything from a
certain point to the end. This is fairly simple:
Select items 1 through 3
arr[1..3]
Select items from the beginning through 5
arr[0..5]
Select items from 5 through the end
arr[5..]
Select whole range
arr[0..]
Write a part of a string
string str = "The cheese stands alone.";
write(str[4..10]);
//Output: "cheese"
2) Last items of an array - Every now and then you just need to select either
the last entry or have a range that always deals with items near the end. The
old way to do this would be to do arr[sizeof(arr)-1] for the last entry. An
easier way is arr[<1].
Select last entry in an array
arr[<1]
Select next to last entry
arr[<2]
Select last three items in an array
arr[<3..]
Use length from end of array to add commas to a number for display
int i = 1234567890;
string str = ""+i;
i = ((sizeof(str)%3)) ? sizeof(str)/3 : (sizeof(str)/3) - 1;
for(; i > 0; i--) {
str = str[0..<((i*3)+1)]+","+str[<(i*3)..];
}
write(str);
// Output = "1,234,567,890"
3) For Each Mappings - With arrays, you have the ability to toss them into a
foreach statement to cycle through each element of the array. You can also do
this with mappings, but it is a little different. You can grab the key for
each item as well as the value in the foreach statement.
Array foreach setup
string item, *arr = ({"A","B","C"});
foreach(item in arr) write(item);
Mapping foreach setup
mapping m = (["EST": -5, "CST": -6, "MST": -7, "PST": -8]);
mixed item;
string str;
foreach(str, item in m) write(str+": "+item);
4) Make your own inherits and includes - If you're writing the same code more
than twice, you need to either toss it into an include or create an inherit
for the objects you're making. This is usually helpful for when you have a
special add_action or other repeating code throughout an area. First off, it
makes it easier to keep track of changes as well as makes it easier for anyone
to maintain in the future after you decide to code Calamari and disappear from
the face of the planet.
To create your own custom inherit, just create a file with the base code you
want. If you're writing a series of rooms with the same special functions in
them, then make sure to inherit /std/room at the top of your .c inherit file
and put all of the special functions in. Now, when you write your rooms, you
just inherit your special room file instead of the normal room file. It'll
have all of the normal room features in addition to your special functions.
Includes are much the same, but you're not choosing a base item to inherit
from. Instead, you simply put all of the code that does the work into its own
.h file. This could be used for a list of defines like most planets use or a
series of functions that a certain type of object needs. These functions and
defines need to be fairly object independant so that you don't have errors
when including them in different projects.
5) Inline If Statements - These conditional statements are handy in a lot of
places to make your functions a little bit more dynamic. They can be used to
bold every other line in a list or double-check what you really want to assign
a variable to.
You simply do a boolean check like you'd normally do for an if statement
followed by a question mark then what happens if it is true. After that, you
put a colon followed by what happens if it is false. This is all usually
encapsulated in a set of parenthsis to prevent the rest of your code from
getting confused.
Display a list bolding every other line
string *arr = ({ "Butter","Milk","Eggs","Bread","Cinnamon" });
int i;
for(i=0;i<sizeof(arr);i++)
write( ((i%2) ? bold(arr[i]) : arr[i]) );
/* Output:
Butter
Milk
Eggs
Bread
Cinnamon
*/
Only display people whose name starts with 'i'. Just a quick note, if all
you care about is 1/0 aka true/false then you don't need to add the extra
part with the question mark and colon.
string *arr;
arr = filter(users()->query_name(),(: ($1[0] == 'i') :) );
map(arr,(: write(capitalize($1)) :) );
//Displays each person whose name starts with 'i' on its own line
6) Sprintf() - As much as I love sprintf, it's not the most efficient function
on the planet. You'll usually be better off with a simple write() unless you
are trying to do more advanced text formatting. However, if text formatting
is what you're after, this is the puppy for the job.
The main thing you need to learn about sprintf() is its formatting syntax.
Every place you want a variable printed is swapped with a formatting code.
This will always start with a percentage sign followed by the options and
ending in the variable type. The most basic version is just the percent and
the variable type (ie: "%s"). So, let's talk variable types first so you know
what you're looking at.
Variable types:
s - String This is what you'll probably be using most of the time.
d - Integer This is likely to be your second most used type.
i - Integer The exact same as d
o - Octal Well, it's still an integer, but it displays as an octal.
c - Char This is an integer from 0-255 as a single character.
x - hex Integer displayed in lowercase hexidecimal format.
X - HEX Same as the above, but in uppercase.
f - float Floating decimal value complete with rounding errors.
O - Object Objects in "/file#number" format, but has other uses.
Next we'll get into the formatting codes. Those are everything between the
percent sign and the variable type (ie: in "%|80s" its the "|80"). First off,
everything defaults to right aligned. Yes, that might seem silly, but it
makes sense if you realize that most of the time you're formatting numbers and
they work better that way. Let's go through them. For reference, "n"
represents any number and the quotes are only around specific characters used.
Generic formatting codes:
n - Any number letting you set the width of variable's column. There's
actually a cheat to this one. If you use "*" in the format string,
then it will take an extra numeric variable right before as the width
(ie: sprintf("%*s",53,"test") instead of sprintf("%53s","test") )
"-" - Left justify the variable within the column width. Best for strings.
"|" - Centers it within the column. Great for column headers.
"=" - Forces continuations of an item down a line, but in the same column.
Tellhist uses it on the message part to get the wrap.
"'X'" - This is a fun one. It fills in the X characters as filler. However,
you can cheat this one as well and give it a width to fill with an
empty variable to have it create a border or break line.
"@" - This is so you can pass an array into sprintf(). There aren't a lot
of good uses for this one by itself, but you can do some fun things
when combining one using this and a width 1 larger than you need and
a sprintf() using "=" at the width you need for a nice column format.
Numberformatting codes:
" " - Pads the number with spaces (ie: " 123")
"+" - Pads positive numbers with a plus sign. (ie: " +123")
"0"n - Putting a 0 before the column width pads the number with zeros (ie:
"0000123").
"."n - Sets the 'precision' of the number. However, it cuts it from the
beginning, not the end and has nothing to do with decimals.
":"n - Sets the precision and column width at the same time to prevent
spillover.
Using sprintf to display info from a mapping including a spacer
mapping *ms = ({ (["sym": "TIG", "price": 3143]),
(["sym": "UFD", "price": 3144]),
(["sym": "VDR", "price": 2156])
});
write(sprintf("%20s %3s %-6s","","SYM","PRICE"));
write(" ----------");
map(ms,(: write(sprintf("%20s %3s %6d","",$1["sym"],$1["price"])) :));
/* Output:
SYM PRICE
----------
TIG 3143
UFD 3144
VDR 2156
*/
Display a list of users online with 4 names per line by processing an array.
string *arr;
arr = filter(users()->query_name(),(: ($1 != 0) :));
arr = map(arr,(: capitalize($1) :));
write(sprintf("%-20@s",arr));
/* Output example:
Ichthus Tantrum Delta Tigwyk
Cthrek Buhlvai Stavros
*/
Creating column widths on the fly for a graphical health bar
int total = 10, current = 7, diff = -2;
string bar;
bar = sprintf("[%*'#'s%*'"+((diff>0) ? "+" : "-")+"'s%*' 's]",
(current-abs(diff)),"",abs(diff),"",(total-(current)),"");
write(bar);
// Output: "[#####-- ]"
7) Sscanf Junk Variables Are Bad - Sometimes when using sscanf to check a
string, you don't necessarily want each substring you're checking for. You'll
see a lot of code where the wizard created a junk or temp variable to toss
this unused information into. That's really a waste of memory and processor
time storing it. Instead, you can tell sscanf that you don't care about that
item by using an asterisk. The number of substrings you're checking won't
change, but the number of variables you're tossing it into will.
Just checking syntax without storing anything
sscanf(str, "park the %*s in the %*s")
// Returns 2 when sent "park the car in the harvard yard"
Storing just part of the info
int id;
sscanf(file_name(this_object()),"%*s#%d", id);
//This is used in space code for grabbing the ship number.
8) Four Holy Efuns - The four most powerful and often used Efuns are explode,
implode, filter, and map. I'd also like to state that I stole part of this
from the Discworld Mud's LPC for Dummies guide. Explode is used to break
apart a string into an array. Map and filter are used to manipulate that
array. Implode is used to put the array back together into a string
(usually). All of them, with the exception of explode, can be passed a
function pointer which allows for fast string and array manipulation. This
can significantly shorten your code and remove a lot of for/foreach/while
loops.
Reversing a string (in this case a palindrome sentence)
string str = "Go hang a salami, I'm a lasagna hog.";
str = implode(explode(str,""),(: $2+$1 :)); return str
// str == ".goh angasal a m'I ,imalas a gnah oG"
Adding an array of integers
int i, *arr = ({1,3,5,7,9,11});
i = implode(arr,(: $1+$2 :));
// i == 36
You can use map(*arr,str) as a quick foreach loop
string str = "john james josh jim joseph";
map(explode(str," "),(: write($1) :));
// prints out each name on its own line
Combine an array, place commas, 'and', alphabetize, capitalize
string *arr=({"north","east","west","south","up","down"});
string str;
// Because our implode setup in this case reverses the order, we're going
// to start in reverse alphabetical so it'll end the correct way.
// The easy way to do this is use strcmp() in the wrong order.
arr = sort_array(arr,(: strcmp($2,$1) :));
str = implode(map(arr,(:capitalize($1):)),
(: (!strcnt($1,", and ")) ? $2+", and "+$1 : $2+", "+$1 :));
//str == "Down, East, North, South, Up, and West"
List all prime slicer players
string *arr;
arr = map(filter(users(),
(: "slicer"==$1->query_primary_guild() :)),
(: capitalize($1->query_name()) :));
// 'arr' contains an array of all prime slicers online

Вам также может понравиться