|
Author |
Topic: Code Snippets |
Title: Member
Posts: 274
Joined: 31 Mar 2007
|
Date Posted: Wed Mar 17, 2010 6:24 pm
Subject: Code Snippets Date Edited: Sun May 21, 2017 8:46 pm (edits total: 15) Edited By: Lucien
|
Edit, many years later:
I really suggest you don't try to use this code. I can't even get it to work myself as-is. If you'd like to see the updated versions of these snippets, I'm slowly adding them to the open-source repo at https://github.com/luciensadi/AwakeMUD.
-- Lucien.
FAIR WARNING: A lot of this code was hastily slapped together to implement features I thought would be interesting to have. Unfortunately, due to the haste with which they were written, these snippets are BUGGY. Use at your own risk.
I'm going to use this thread to post snippets of code for anyone who would like to try them- they're working great on my port, and they should work well with any other running .20 port as well. All I ask is that you credit me somehow if you do use them.
Index of Code Snippets:
---
First, code that makes speech by invisible people use their voice-desc:
Quote: | DAS INVISIBLEDUDE slides an invisibility ring on to his right ring finger.
<pP>
> l
The Testing Room
DESC IS NOT NECESSARY FOR KROOG. KROOG SMASH CODE.
Obvious exits:
North - Welcome to Awakened Worlds!
<pP>
A voice like death incarnate says, in English, "Hi there!" |
You need to do a few things to make this work. First, go into COMM.CPP and add a 'z' case to the $var interpreter- it's around line 2239. Paste the following code in right after the Switch line:
Code: | case 'z':
if (to == ch)
i = "you";
else if (CAN_SEE(to, ch))
if (IS_SENATOR(to) && !IS_NPC(ch))
i = GET_CHAR_NAME(ch);
else
i = make_desc(to, ch, buf, TRUE);
else {
if (IS_NPC(ch))
i = GET_NAME(ch);
else {
if (IS_SENATOR(ch)) {
i = "someone";
} else if ((mem = found_mem(GET_MEMORY(to), ch))) {
sprintf(temp, "%s(%s)", ch->player.physical_text.room_desc, CAP(mem->mem));
i = temp;
} else {
i = ch->player.physical_text.room_desc;
}
}
}
break;
|
Next, go to ACT.COMM.CPP and look at the DO_SAY ACMD. It will have lines like the following seeded through it:
Code: | sprintf(buf, "$n says%s, in %s, \"%s^n\"", |
All you need to do is change the $n to $z in order to use the new invisibility-voice code. As an aside, you should note that invisible Immortals will still show up as 'Someone'.
-----signature----- :::The Star Sapphire:::
|
Post Reply | Quote | Private Message
|
Title: Member
Posts: 274
Joined: 31 Mar 2007
|
Date Posted: Wed Mar 17, 2010 6:41 pm
Subject: Date Edited: Sat Mar 20, 2010 4:49 pm (edits total: 3) Edited By: Lucien
|
The TKE Command:
Quote: | > tke
Your current TKE is 54. |
This one's simple to add. Open up the source file of your choice (I used ACT.INFORMATIVE.CPP) and paste the following in:
Code: | ACMD(do_tke){
sprintf(buf, "Your current TKE is %d.\r\n", GET_TKE(ch));
send_to_char(buf, ch);
} |
Save and close. Next, open up INTERPRETER.CPP. Scroll down a little until you see that huge pillar of ACMD(whatever);- this is where you'll be adding your new command. Go to the correct alphabetical place (exactness not required) and put in:
Now to add the actual interpretation. Go to the area around line 900 and put in the following line in the T-block:
Code: | { "tke" , POS_DEAD , do_tke , 0, 0 }, |
And you're done! One TKE command, ready and waiting for duty.
EDITS:
[3/20/10] Updated for in-game formatting.
-----signature----- :::The Star Sapphire:::
|
Post Reply | Quote | Private Message
|
Title: Member
Posts: 274
Joined: 31 Mar 2007
|
Date Posted: Thu Mar 18, 2010 12:00 am
Subject: Date Edited: Sat Mar 20, 2010 4:50 pm (edits total: 4) Edited By: Lucien
|
Vehicular Speech Function:
You, too, can experience the magic of hearing people outside your vehicle talk! (Note, this requires the above invisible-voice modification to be installed as well.)
As an aside, this upgrade also resolves the issue of having osays within vehicles show up as descriptions- they now properly resolve as name/desc/voice where appropriate.
Quote: | Invis arrives from a puff of smoke.
<pP>
> enter jack
You climb into A Jackrabbit-E.
<pP>
Outside your vehicle, Invis says, in English, "Test!"
(Invis turns invisible here.)
<pP>
Outside your vehicle, a voice like death incarnate(Invis) says, in English, "Test again!" |
ACT.COMM.CPP:
Go to line 74 and look for the SCMD_OSAY ifcheck. Replace its contents with the following:
Code: | for (tmp = ch->in_veh->people; tmp; tmp = tmp->next_in_veh){
sprintf(buf,"$z says ^mOOCly^n, \"%s^n\"\r\n", argument);
act(buf, FALSE, ch, NULL, tmp, TO_VICT);
} |
Go to line ~120 and look for the next SCMD_OSAY. ADD the following code to the bottom of the ifcheck:
Code: | int j = 100;
for (struct veh_data *i = world[ch->in_room].vehicles; i && (j > 0); i = i->next_veh){
for (tmp = i->people; tmp; tmp = tmp->next_in_veh){
sprintf(buf,"Outside your vehicle, $z says ^mOOCly^n, \"%s^n\"\r\n", argument);
act(buf, FALSE, ch, NULL, tmp, TO_VICT);
}
//send_to_veh(buf, i, ch, FALSE);
j--;
} |
Now, go to line ~158 to find the end of this else-check. At the bottom of the else-check (still inside, it mind you), add the following code block:
Code: | int j = 100;
for (struct veh_data *i = world[ch->in_room].vehicles; i && (j > 0); i->next_veh){
for (tmp = i->people; tmp; tmp = tmp->next_in_veh){
if (tmp != ch && !(IS_ASTRAL(ch) && !CAN_SEE(tmp, ch))) {
if (to) {
sprintf(buf2, " to %s", CAN_SEE(tmp, to) ? (found_mem(GET_MEMORY(tmp), to) ? CAP(found_mem(GET_MEMORY(tmp), to)->mem): GET_NAME(to)) : "someone");
}
}
if (success > 0) {
suc = success_test(GET_SKILL(tmp, GET_LANGUAGE(ch)), 4);
if (suc > 0 || IS_NPC(tmp)) { sprintf(buf, "Outside your vehicle, $z says%s, in %s, \"%s^n\"", (to ? buf2 : ""), skills[GET_LANGUAGE(ch)].name, argument); }
else { sprintf(buf, "Outside your vehicle, $z speaks%s in a language you don't understand.", (to ? buf2 : "")); }
}
else { sprintf(buf, "Outside your vehicle, $z mumbles incoherently."); }
if (IS_NPC(ch)) { sprintf(buf, "Outside your vehicle, $z says%s, \"%s^n\"", (to ? buf2 : ""), argument); }
act(buf, FALSE, ch, NULL, tmp, TO_VICT);
}
j--;
} |
Final note: Since this one's a complex one, it may be that I've missed a section of code to add. If it doesn't work for you, let me know and I'll look over my changes to see if I missed some snippet you need.
EDITS:
[3/17/10] Fixed a forum bug where it stripped 'html' from within the code, rendering all code between <> tags useless.
-----signature----- :::The Star Sapphire:::
|
Post Reply | Quote | Private Message
|
Title: Member
Posts: 274
Joined: 31 Mar 2007
|
Date Posted: Thu Mar 18, 2010 12:37 am
Subject: Date Edited: Sun Mar 21, 2010 4:01 am (edits total: 9) Edited By: Lucien
|
Dynamic Ammunition Code
Alright, now -this- one is a massive edit. It's totally worth it, though- in essence, this code massively reduces the strain on the database by making it wholly unnecessary to have a stockpile of clips. Instead of piling up clips with special ammo, you just pile up boxes, and have only a few clips for each weapon. (tl;dr LESS TICKLAG)
DISCLAIMER: Seeing as how long this is, I almost guarantee that I've missed something. As such, don't expect this to compile the first time- just let me know what the errors are and I'll pass along the remaining chunks.
This novel-length snippet will serve to do several things:
- Adds a new class of item, ITEM_NEW_AMMUNITION, which covers ammunition boxes. NEW_AMMUNITION items have the following values:
Code: | 0 [Ammunition Type (0 through 5)
1 [Current Ammunition Quantity]
2 [Ammunition Weapon Class (19 through 27)] |
- Modifies clips to have a flag that declares whether or not they can hold APDS ammunition in order to allow APDS to be restricted to certain weapons/classes like it is now. Modified GUN_CLIP items have the following values:
Code: | 0 [Ammunition Quantity at Item Creation]
1 [Weapon Type (19 through 27)]
2 [Ammunition Type (0 through 5)]
3 [Unused]
4 [Flag: Can Contain APDS (1 is yes, 0 is no)]
9 [Current Ammunition Load] |
Worthy of note is that the APDS flag's default (0) is NO, meaning all current clips will be incapable of holding APDS unless updated.
- Adds the LOAD and UNLOAD commands to the game, allowing you to load and unload clips with a single type of ammunition. These commands will not allow the mixing of ammunition.
- Adds the functionality of combining NEW_AMMUNITION items together like parts and chips for ease of storage.
PROCEDURE FOR ADDING NEW CODE:
First, we need to define the actual ITEM_NEW_AMMUNITION value. In AWAKE.H, scroll down to ~950, where the #define ITEM block is. Add the following define:
Code: | #define ITEM_NEW_AMMUNITION 42 |
Modify the NUM_ITEMS define to 43.
Next, we need to modify the OLC to allow the creation of this new item class. Open up IEDIT.CPP and scroll down to ~380, just before the line "default:". Insert the following code:
Code: | case ITEM_NEW_AMMUNITION:
send_to_char(" 0) Normal 1) APDS\r\n"
" 2) Explosive 3) EX\r\n"
" 4) Flechette 5) Gel\r\n"
"Select Type: ", CH);
break; |
Scroll to line ~500, just before the default again. Add:
Code: | case ITEM_NEW_AMMUNITION:
send_to_char("Ammunition quantity: ", CH);
break; |
Scroll to line ~620 (before the default). Add:
Code: | case ITEM_NEW_AMMUNITION:
send_to_char(" 1) Pistol 2) Blast\r\n"
" 3) Rifle 4) Shotgun\r\n"
" 5) Machine gun 6) Cannon\r\n"
" 7) Grenade launcher 8) Rocket\r\nClip type: ", CH);
break; |
Scroll to line ~740. Again, before the default, add:
Code: | case ITEM_GUN_CLIP:
send_to_char("Can contain APDS: (1 for yes, 0 for no): ", CH);
break; |
Now scroll to ~1800. Just before the default, put:
Code: | case ITEM_NEW_AMMUNITION:
if((!(number > -1)) || (number > 5)) {
send_to_char("Type of ammunition must be between 0 and 5 (inclusive).\r\n", CH);
send_to_char("Type of ammo: ", CH);
return;
}
break; |
Now you need to go to the area around 2070. Before the default, insert:
Code: | case ITEM_NEW_AMMUNITION:
if (!(number > 0) || number > 8) {
send_to_char("Invalid option!\r\nAmmo class: ", CH);
return;
}
number += 20;
if (number == 27){ number = 19; }
if (number == 28){ number = 20; }
break;
default:
break;
} | .
Now, go down a bit to IEDIT_VALUE_4. Inside this switch statement, put:
Code: | case ITEM_GUN_CLIP:
if( (number != 1) && (number != 0) ){
send_to_char("Invalid selection- must be 1 or 0: ", d->character);
return;
}
break; |
...ALL THAT JUST TO BE ABLE TO CREATE THE ITEM WITH THE OLC! *tinfoil hat, crazed grin*
More to follow in the upcoming posts.
EDITS:
[3/20/10] Moved the block from 1950 (objval 1) to 1800 (objval 0) so that it would define boundaries for the proper function. Added a clarifying statement to the same block.
[3/20/10] Added a missed block that was required to properly set the class of ammunition in the pile.
[3/20/10] Bugfix concerning the modified ifchecks that were changed to accommodate the forum's HTML-parsing code.
-----signature----- :::The Star Sapphire:::
|
Post Reply | Quote | Private Message
|
Title: Member
Posts: 274
Joined: 31 Mar 2007
|
Date Posted: Thu Mar 18, 2010 12:53 am
Subject: Date Edited: Sun Mar 28, 2010 5:10 am (edits total: 4) Edited By: Lucien
|
Great! Now we can create our ammunition dump in OLC. (The previous code also covered the inclusion of the APDS flag on gun clips.)
Now we need to add in the commands that allow us to load and unload our clips. Thankfully, this one's more about pasting in giant code-chunks instead of doing that tedious line-by-line bullshit I had you doing earlier. (Sorry!)
Go to ACT.OBJ.CPP. Go to the whitespace after the end of the 'bool search_cyberdeck' function (it's right near the top). Paste in the following function:
Code: | int CALCULATE_VALUE_OF_NEWAMMO(obj_data *obj){
enum AmmoCost_Multiplier { STANDARD = 1, APDS = 10, EXPLOSIVE = 5, EX = 8, FLECHETTE = 2, GEL = 1, DEFAULT = 1 };
AmmoCost_Multiplier multiplier;
switch(GET_OBJ_VAL(obj, 0)){
case(0): multiplier = STANDARD ; break;
case(1): multiplier = APDS ; break;
case(2): multiplier = EXPLOSIVE ; break;
case(3): multiplier = EX ; break;
case(4): multiplier = FLECHETTE ; break;
case(5): multiplier = GEL ; break;
default: multiplier = DEFAULT; break;
}
return multiplier * GET_OBJ_VAL(obj, 1);
} |
The name is only yelling at you because it loves you so much.
Time to add in the bulk of the load/unload code! Paste the following block after the end of that function you just inserted:
Code: | ACMD(do_unload)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
struct obj_data *obj, *next_obj, *cont;
struct char_data *tmp_char;
int obj_dotmode, cont_dotmode, found = 0;
if (IS_WORKING(ch)) {
send_to_char(TOOBUSY, ch);
return;
}
if (IS_ASTRAL(ch)) {
send_to_char("You can't!\r\n", ch);
return;
}
two_arguments(argument, arg1, arg2);
obj_dotmode = find_all_dots(arg1);
cont_dotmode = find_all_dots(arg2);
if (!*arg1) {
sprintf(buf, "Unload what into what?\r\n");
send_to_char(buf, ch);
}
else if (obj_dotmode != FIND_INDIV) {
sprintf(buf, "You can only unload clips into one box at a time.\r\n");
send_to_char(buf, ch);
}
else if (!*arg2) {
sprintf(buf, "What do you want to empty it into?\r\n");
send_to_char(buf, ch);
}
else {
generic_find(arg2, FIND_OBJ_EQUIP | FIND_OBJ_INV | FIND_OBJ_ROOM, ch, &tmp_char, &cont);
if (!cont) {
sprintf(buf, "You don't see %s %s here.\r\n", AN(arg2), arg2);
send_to_char(buf, ch);
}
else if (obj == cont)
send_to_char(ch, "You cannot unload an item into itself.\r\n");
else if (GET_OBJ_TYPE(cont) != ITEM_NEW_AMMUNITION) {
sprintf(buf, "$p is not an ammo container.");
act(buf, FALSE, ch, cont, 0, TO_CHAR);
}
else if (GET_OBJ_TYPE(cont) == ITEM_NEW_AMMUNITION) {
if (!(obj = get_obj_in_list_vis(ch, arg1, ch->carrying)))
send_to_char(ch, "You aren't carrying %s %s.\r\n", AN(arg1), arg1);
else if(!(GET_OBJ_VAL(obj, 9) > 0)){
send_to_char(ch, "It's already empty.\r\n");
}
else if (GET_OBJ_TYPE(obj) != ITEM_GUN_CLIP){
sprintf(buf, "$p is not a clip.");
act(buf, FALSE, ch, obj, 0, TO_CHAR);
}
else if (GET_OBJ_VAL(cont, 2) != GET_OBJ_VAL(obj, 1))
send_to_char(ch, "The box contains a different class of ammunition.\r\n");
else if (GET_OBJ_VAL(obj, 2) != GET_OBJ_VAL(cont, 0))
send_to_char(ch, "You cannot mix ammunition types together.\r\n");
else {
GET_OBJ_VAL(cont, 1) += GET_OBJ_VAL(obj, 9);
GET_OBJ_VAL(obj, 9) = 0;
send_to_char(ch, "You empty the clip.\r\n");
GET_OBJ_COST(cont) = CALCULATE_VALUE_OF_NEWAMMO(cont);
act("$n empties $p into $P.", FALSE, ch, obj, cont, TO_ROOM);
}
}
else {
for (obj = ch->carrying; obj; obj = next_obj) {
next_obj = obj->next_content;
if (obj != cont && CAN_SEE_OBJ(ch, obj) &&
(obj_dotmode == FIND_ALL || isname(arg1, obj->text.keywords))) {
found = 1;
}
}
if (!found) {
if (obj_dotmode == FIND_ALL) {
sprintf(buf, "You don't seem to have anything to unload into it.\r\n");
send_to_char(buf, ch);
} else {
sprintf(buf, "You don't seem to have any %ss.\r\n", arg1);
send_to_char(buf, ch);
}
}
}
}
}
ACMD(do_newload)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
struct obj_data *obj, *next_obj, *cont;
struct char_data *tmp_char;
int obj_dotmode, cont_dotmode, found = 0;
if (IS_WORKING(ch)) {
send_to_char(TOOBUSY, ch);
return;
}
if (IS_ASTRAL(ch)) {
send_to_char("You can't!\r\n", ch);
return;
}
two_arguments(argument, arg1, arg2);
obj_dotmode = find_all_dots(arg1);
cont_dotmode = find_all_dots(arg2);
if (!*arg1) {
sprintf(buf, "Load what into what?\r\n");
send_to_char(buf, ch);
}
else if (obj_dotmode != FIND_INDIV) {
sprintf(buf, "You can only load rounds into one clip at a time.\r\n");
send_to_char(buf, ch);
}
else if (!*arg2) {
sprintf(buf, "What do you want to load them into?\r\n");
send_to_char(buf, ch);
}
else { // source found, single target found.
generic_find(arg1, FIND_OBJ_EQUIP | FIND_OBJ_INV | FIND_OBJ_ROOM, ch, &tmp_char, &cont);
if (!cont) {
sprintf(buf, "You don't see %s %s here.\r\n", AN(arg2), arg2);
send_to_char(buf, ch);
}
else if (obj == cont)
send_to_char(ch, "You cannot load an item into itself.\r\n");
else if (GET_OBJ_TYPE(cont) != ITEM_GUN_CLIP) {
sprintf(buf, "$p is not a clip.\r\n");
act(buf, FALSE, ch, cont, 0, TO_CHAR);
}
else if (GET_OBJ_TYPE(cont) == ITEM_GUN_CLIP) {
if (!(obj = get_obj_in_list_vis(ch, arg2, ch->carrying)))
send_to_char(ch, "You aren't carrying %s %s.\r\n", AN(arg2), arg2);
else if (GET_OBJ_TYPE(obj) != ITEM_NEW_AMMUNITION){
sprintf(buf, "$p is not an ammunition box.\r\n");
act(buf, FALSE, ch, obj, 0, TO_CHAR);
}
else if(GET_OBJ_VAL(cont, 9) == GET_OBJ_VAL(cont, 0)){
send_to_char(ch, "It's already full.\r\n");
}
else if (GET_OBJ_VAL(cont, 9) > 0 && (GET_OBJ_VAL(obj, 0) != GET_OBJ_VAL(cont, 2))){
send_to_char(ch, "You cannot mix ammunition types together.\r\n");
}
else if (GET_OBJ_VAL(obj, 2) != GET_OBJ_VAL(cont, 1)){
send_to_char(ch, "The clip isn't made to hold that class of ammunition.\r\n");
}
else if (GET_OBJ_VAL(obj, 0) == 1 && GET_OBJ_VAL(cont, 3) != 1){
send_to_char(ch, "That clip isn't made to hold APDS ammunition.\r\n");
}
else if (GET_OBJ_VAL(cont, 0) > (GET_OBJ_VAL(obj, 1) - GET_OBJ_VAL(cont, 9))){
if(!(GET_OBJ_VAL(cont, 9) > 0)){
GET_OBJ_VAL(cont, 2) = GET_OBJ_VAL(obj, 0);
}
GET_OBJ_VAL(cont, 9) += GET_OBJ_VAL(obj, 1);
send_to_char(ch, "You load the last of your ammunition into the clip.\r\n");
act("$n loads the last of the ammunition from $P into $p.", FALSE, ch, obj, cont, TO_ROOM);
extract_obj(obj);
}
else {
if(!(GET_OBJ_VAL(cont, 9) > 0)){
GET_OBJ_VAL(cont, 2) = GET_OBJ_VAL(obj, 0);
}
GET_OBJ_VAL(obj, 1) -= GET_OBJ_VAL(cont, 0) - GET_OBJ_VAL(cont, 9);
GET_OBJ_VAL(cont, 9) = GET_OBJ_VAL(cont, 0);
GET_OBJ_COST(obj) = CALCULATE_VALUE_OF_NEWAMMO(obj);
send_to_char(ch, "You fill the clip.\r\n");
act("$n loads $p from $P.", FALSE, ch, cont, obj, TO_ROOM);
}
}
else {
for (obj = ch->carrying; obj; obj = next_obj) {
next_obj = obj->next_content;
if (obj != cont && CAN_SEE_OBJ(ch, obj) &&
(obj_dotmode == FIND_ALL || isname(arg1, obj->text.keywords))) {
found = 1;
}
}
if (!found) {
if (obj_dotmode == FIND_ALL) {
sprintf(buf, "You don't seem to have anything to load into it.\r\n");
send_to_char(buf, ch);
} else {
sprintf(buf, "You don't seem to have any %ss.\r\n", arg1);
send_to_char(buf, ch);
}
}
}
}
} |
Jesus, that's long. But on the plus side, that's the entirety of the load-unload function! Now, while we're here in act.obj, let's go ahead and add the ammo-combining function:
Scroll down to ~630 and replace this block with the following block:
Code: | else if ((GET_OBJ_TYPE(cont) == ITEM_DECK_ACCESSORY && GET_OBJ_VAL(cont, 0) == TYPE_PARTS) ||
(GET_OBJ_TYPE(cont) == ITEM_MAGIC_TOOL && GET_OBJ_VAL(cont, 0) == TYPE_SUMMONING)) {
if (!(obj = get_obj_in_list_vis(ch, arg1, ch->carrying)))
send_to_char(ch, "You aren't carrying %s %s.\r\n", AN(arg1), arg1);
else if (obj == cont)
send_to_char(ch, "You cannot combine an item with itself.\r\n");
else if (GET_OBJ_TYPE(cont) != GET_OBJ_TYPE(obj) || GET_OBJ_VAL(obj, 0) != GET_OBJ_VAL(cont, 0))
send_to_char(ch, "You cannot combine those two items.\r\n");
else {
GET_OBJ_COST(cont) += GET_OBJ_COST(obj);
send_to_char(ch, "You combine %s and %s.\r\n", GET_OBJ_NAME(cont), GET_OBJ_NAME(obj));
extract_obj(obj);
} |
Code: | else if ((GET_OBJ_TYPE(cont) == ITEM_DECK_ACCESSORY && GET_OBJ_VAL(cont, 0) == TYPE_PARTS) ||
(GET_OBJ_TYPE(cont) == ITEM_MAGIC_TOOL && GET_OBJ_VAL(cont, 0) == TYPE_SUMMONING) ||
(GET_OBJ_TYPE(cont) == ITEM_NEW_AMMUNITION)) {
if (!(obj = get_obj_in_list_vis(ch, arg1, ch->carrying)))
send_to_char(ch, "You aren't carrying %s %s.\r\n", AN(arg1), arg1);
else if (obj == cont)
send_to_char(ch, "You cannot combine an item with itself.\r\n");
else if (GET_OBJ_TYPE(cont) != GET_OBJ_TYPE(obj) || GET_OBJ_VAL(obj, 0) != GET_OBJ_VAL(cont, 0))
send_to_char(ch, "You cannot combine those two items.\r\n");
else if (GET_OBJ_TYPE(cont) == ITEM_NEW_AMMUNITION){
GET_OBJ_VAL(cont, 1) += GET_OBJ_VAL(obj, 1);
GET_OBJ_COST(cont) = CALCULATE_VALUE_OF_NEWAMMO(cont);
send_to_char(ch, "You repackage the ammunition.\r\n");
extract_obj(obj);
} |
You're getting there! More to come.
EDITS:
[3/20/10] Updated code for in-game formatting.
[3/28/10] Fixed the APDS check.
-----signature----- :::The Star Sapphire:::
|
Post Reply | Quote | Private Message
|
Title: Member
Posts: 274
Joined: 31 Mar 2007
|
Date Posted: Thu Mar 18, 2010 12:58 am
Subject:
|
Alright, now it's time to make ACT.INFORMATIVE.CPP our little bitch. Open it up and go to the part right after the blood stuff (or after the TKE function, if you added that in too). Plop the following code in:
Code: | char* PARSE_NEWAMMO(int atype, int wtype){
string ammotype, weapontype;
switch(atype){
case 0: ammotype = "standard"; break;
case 1: ammotype = "APDS"; break;
case 2: ammotype = "explosive"; break;
case 3: ammotype = "EX"; break;
case 4: ammotype = "flechette"; break;
case 5: ammotype = "gel"; break;
default: ammotype = "UNDEFINED"; break;
}
switch(wtype){
case 19: weapontype = " grenade launcher round"; break;
case 20: weapontype = " rocket"; break;
case 21: weapontype = " pistol round"; break;
case 22: weapontype = " blast weapon round"; break;
case 23: weapontype = " rifle round"; break;
case 24: weapontype = " shotgun shell"; break;
case 25: weapontype = " machine gun round"; break;
case 26: weapontype = " assault cannon shell"; break;
default: weapontype = " UNDEFINED lump"; break;
}
return (char*) ((ammotype + weapontype).c_str());
} |
Go down to ~1640 and look for the else-if block talking about ITEM_GUN_CLIP. Replace this block with:
Code: | else if (GET_OBJ_TYPE(tmp_object) == ITEM_GUN_CLIP){
sprintf(buf, "%s%s", PARSE_NEWAMMO(GET_OBJ_VAL(tmp_object, 2), GET_OBJ_VAL(tmp_object, 1)), GET_OBJ_VAL(tmp_object, 9) != 1 ? "s" : "");
send_to_char(ch, "It has %d %s left.\r\n", GET_OBJ_VAL(tmp_object, 9), buf);
} |
Now, scroll to 1664 ish and look for the line telling you how much nuyen you've got in your cyberdeck chip/parts bag/box. Add the following after that check:
Code: | else if (GET_OBJ_TYPE(tmp_object) == ITEM_NEW_AMMUNITION){
sprintf(buf, "It seems to contain about %d %s%s.\r\n", GET_OBJ_VAL(tmp_object, 1), PARSE_NEWAMMO(GET_OBJ_VAL(tmp_object, 0), GET_OBJ_VAL(tmp_object, 2)), GET_OBJ_VAL(tmp_object, 1) != 1 ? "s" : "");
send_to_char(ch, buf);
} |
And, finally, we get to add the command itself. Go on over to INTERPRETER.CPP!
In the ACMD column, add ACMD(do_unload); and ACMD_(do_newload); .
In the 'L' section of the main command interpreting table, add:
Code: | { "load" , POS_SITTING, do_newload , 0, 0 }, |
In the 'U' section of the main command interpreting table, add:
Code: | { "unload" , POS_SITTING , do_unload , 0, 0 }, |
Now, this -does- create a conflict with the previous Immortal 'load' command, used for loading up characters who are otherwise disconnected. I suggest modifying this 'load' command to be 'loadchar', which is done simply by modifying the other 'load' line to read 'loadchar'.
...And that's it! Congratulations.
-----signature----- :::The Star Sapphire:::
|
Post Reply | Quote | Private Message
|
Title: Site Admin
Posts: 557
Joined: 03 Apr 2005
|
Date Posted: Thu Mar 18, 2010 6:46 am
Subject:
|
That other load command isn't an imm command. It's the load command for the matrix
|
Post Reply | Quote | Private Message
|
Title: Member
Posts: 274
Joined: 31 Mar 2007
|
Date Posted: Thu Mar 18, 2010 6:56 am
Subject:
|
I was talking about the do_wizload command:
Code: | { "load" , POS_RESTING , do_wizload , 0, 0 }, |
It's under the main struct with the direction commands- aren't Matrix commands separate?
EDIT: Yeah, the matrix one is do_load, under the matrix command table:
Code: | { "load", 0, do_load, 0, SCMD_SWAP}, |
EDIT 2: Althought I was wrong about what it does- the do_wizload command apparently loads objects, mobs or vehicles.
-----signature----- :::The Star Sapphire:::
|
Post Reply | Quote | Private Message
|
Title: Member
Posts: 274
Joined: 31 Mar 2007
|
Date Posted: Thu Mar 18, 2010 3:30 pm
Subject: Date Edited: Sat Mar 20, 2010 7:07 pm (edits total: 1) Edited By: Lucien
|
The Eject Command:
For quick and easy clip recovery from a weapon, use EJECT!
Quote: | The 950 is the big sister of the 750; it packs a slightly larger punch and
also comes with a scope.
It contains 5 rounds of Normal ammunition, and can hold 5 rounds.
> eject
You eject a clip from a Remington 950 sport rifle.
> exam rem
The 950 is the big sister of the 750; it packs a slightly larger punch and
also comes with a scope.
It does not contain any ammunition, but looks to hold 5 rounds.
|
Insert this code into your ACT.OBJ.CPP file.
Code: | ACMD(do_eject){
struct obj_data *gun;
int n = 0;
if (IS_WORKING(ch)){
send_to_char(TOOBUSY, ch);
return;
}
if (IS_ASTRAL(ch)) {
send_to_char("You can't!\r\n", ch);
return;
}
two_arguments(argument, buf, buf1);
if (!(gun = get_object_in_equip_vis(ch, buf, ch->equipment, &n))){
if (!(gun = get_obj_in_list_vis(ch, buf, ch->carrying))) {
send_to_char(ch, "You don't have a '%s'.\r\n", buf);
return;
}
}
if (GET_OBJ_TYPE(gun) != ITEM_WEAPON){
send_to_char("That's not a weapon.\r\n", ch);
return;
}
if ((!(GET_OBJ_VAL(gun, 3) > TYPE_HAND_GRENADE) && GET_OBJ_VAL(gun, 3) != TYPE_TASER) || !(GET_OBJ_VAL(gun, 5) >= 1)) {
send_to_char("That weapon doesn't use clips.\r\n", ch);
return;
}
if (gun->contains) {
struct obj_data *old = gun->contains;
obj_from_obj(old);
if (ch->in_veh) {
obj_to_veh(old, ch->in_veh);
old->vfront = ch->vfront;
} else {
obj_to_room(old, ch->in_room);
act("$n ejects a clip from $p.", FALSE, ch, gun, NULL, TO_ROOM);
act("You eject a clip from $p.", FALSE, ch, gun, NULL, TO_CHAR);
}
}
else {
send_to_char("That weapon isn't loaded.\r\n", ch);
}
} |
Modify your INTERPRETER.CPP file with the following:
Code: | { "eject" , POS_SITTING , do_eject , 0, 0 }, |
EDITS:
[3/20/10] Part I: I didn't make it clear exactly what happens here- this code snippet performs the first half of the reloading function by ejecting a clip from a weapon and putting it on the ground (or, if you're in a vehicle, the part of the vehicle you're in). Also, I've updated the above code for better in-game formatting.
[3/20/10] Part II: Split the large ifcheck into smaller ones that are less ambiguous.
[3/20/10] Part III: Fixed forum 'I SEE HTML BRACKETS, THIS ATROCITY CANNOT GO UNPUNISHED' parsing problem so that the code will actually work.
-----signature----- :::The Star Sapphire:::
|
Post Reply | Quote | Private Message
|
Title: Member
Posts: 274
Joined: 31 Mar 2007
|
Date Posted: Sat Mar 20, 2010 5:00 pm
Subject:
|
Updated most of the snippets for proper in-game formatting; also bugfixed several snippets. If there's a new 'EDITS' section at the bottom of the post, I updated some of the material in it.
-----signature----- :::The Star Sapphire:::
|
Post Reply | Quote | Private Message
|
Title: Member
Posts: 274
Joined: 31 Mar 2007
|
Date Posted: Sun Mar 21, 2010 12:36 am
Subject: Date Edited: Sun Mar 21, 2010 6:58 am (edits total: 1) Edited By: Lucien
|
Garage Door Opener ("GDO"):
NOTE: THIS CODE IS INCOMPLETE. It lacks support for rigging. I'll update it soon.
Quote: | [ 5000] The Testing Room [ !MOB, INDOORS, GARAGE, STORAGE]
DESC IS NOT NECESSARY FOR KROOG. KROOG SMASH CODE.
[ Exits: n(L) s ]
A Chrysler-Nissan Jackrabbit-E sits silently here. (Yours)
> enter jack
You climb into A Jackrabbit-E.
> gdo n
You swipe the door's key through the magstripe reader.
The garage door to the north hums open.
> leave
You climb out into the street.
> l
[ 5000] The Testing Room [ !MOB, INDOORS, GARAGE, STORAGE]
DESC IS NOT NECESSARY FOR KROOG. KROOG SMASH CODE.
[ Exits: n s ]
A Chrysler-Nissan Jackrabbit-E sits silently here. (Yours) |
This code toggles the state of a door (open/unlocked -> closed/locked and vice versa) when you're in a vehicle and use the GDO command. It only works on doors that you have the key for.
To install it, you need to do several things: First, you need to import a function by adding the following line before 'ACMD(do_return)':
Code: | int has_key(struct char_data *ch, int key); |
Next, you need to add the actual GDO-handling code. Put this before 'ACMD(do_drive)'.
Code: | ACMD(do_gdo)
{
char direction[MAX_INPUT_LENGTH];
int roomnum = 0, door;
if(IS_ASTRAL(ch)){
send_to_char("You can't!\r\n", ch);
return;
}
if(!ch->in_veh){
send_to_char("You need to be inside a vehicle to use its GDO.\r\n", ch);
return;
}
one_argument(argument, direction);
if(!*direction){
send_to_char("Which door would you like to open?\r\n", ch);
return;
}
if(door = search_block(direction, lookdirs, FALSE) == -1){
send_to_char("That's not a valid direction.\r\n", ch);
return;
}
roomnum = ch->in_veh->in_room;
if(!EXIT2(roomnum, door) || EXIT2(roomnum, door)->to_room == NOWHERE){
send_to_char("There is no exit there.\r\n", ch);
return;
}
if(!IS_SET(EXIT2(roomnum, door)->exit_info, EX_ISDOOR)){
send_to_char("There's no door there to open.\r\n", ch);
return;
}
if(!IS_SET(EXIT2(roomnum, door)->exit_info, EX_GDO)){
send_to_char("That door isn't set up with a remote-opening device.\r\n", ch);
return;
}
if(!has_key(ch, EXIT2(roomnum, door)->key)){
send_to_char("You don't have the proper key for that door.\r\n", ch);
return;
}
if (IS_SET(EXIT2(roomnum, door)->exit_info, EX_CLOSED)) {
REMOVE_BIT(EXIT2(roomnum, door)->exit_info, EX_CLOSED);
REMOVE_BIT(EXIT2(roomnum, door)->exit_info, EX_LOCKED);
REMOVE_BIT(EXIT2(EXIT2(roomnum, door)->to_room, rev_dir[door])->exit_info, EX_CLOSED);
REMOVE_BIT(EXIT2(EXIT2(roomnum, door)->to_room, rev_dir[door])->exit_info, EX_LOCKED);
send_to_char("You swipe the door's key through the magstripe reader.\r\n", ch);
for (struct char_data *tmp = ch->in_veh->people; tmp; tmp = tmp->next_in_veh){
if(tmp != ch){
sprintf(buf,"$n swipes $s key through the magstripe reader.");
act(buf, FALSE, ch, NULL, tmp, TO_VICT);
}
}
sprintf(buf, "The %s to the %s hums open.\r\n", EXIT2(roomnum, door)->general_description ? EXIT2(roomnum, door)->keyword : "door" , fulldirs[door]);
send_to_room(buf, roomnum);
sprintf(buf, "The %s to the %s hums open.\r\n", EXIT2(roomnum, rev_dir[door])->general_description ? EXIT2(roomnum, rev_dir[door])->keyword : "door" , fulldirs[door]);
send_to_room(buf, EXIT2(roomnum, door)->to_room);
}
else {
SET_BIT(EXIT2(roomnum, door)->exit_info, EX_CLOSED);
SET_BIT(EXIT2(roomnum, door)->exit_info, EX_LOCKED);
SET_BIT(EXIT2(EXIT2(roomnum, door)->to_room, rev_dir[door])->exit_info, EX_CLOSED);
SET_BIT(EXIT2(EXIT2(roomnum, door)->to_room, rev_dir[door])->exit_info, EX_CLOSED);
send_to_char("You swipe the door's key through the magstripe reader.\r\n", ch);
for (struct char_data *tmp = ch->in_veh->people; tmp; tmp = tmp->next_in_veh){
if(tmp != ch){
sprintf(buf,"$n swipes $s key through the magstripe reader.");
act(buf, FALSE, ch, NULL, tmp, TO_VICT);
}
}
sprintf(buf, "The %s to the %s hums closed.\r\n", EXIT2(roomnum, door)->general_description ? EXIT2(roomnum, door)->keyword : "door" , fulldirs[door]);
send_to_room(buf, roomnum);
sprintf(buf, "The %s to the %s hums open.\r\n", EXIT2(roomnum, rev_dir[door])->general_description ? EXIT2(roomnum, rev_dir[door])->keyword : "door" , fulldirs[door]);
send_to_room(buf, EXIT2(roomnum, door)->to_room);
}
} |
Close ACT.DRIVE and move on to the interpreter. Add in a ACMD(do_gdo) at the top and a corresponding interpreter line in the alphabetical order. The line you'll need is:
Code: | { "gdo" , POS_SITTING , do_gdo , 0, 0 }, |
That will implement the actual command. Now, to add the OLC commands to enable the setting of the flag (and the parsing function to let it save and load the flag to disk). Go to REDIT.CPP and delete lines 148, 149 and 150. Replace them with the following block:
Code: | CCCYN(CH, C_CMP), (IS_SET(DOOR->exit_info, EX_ISDOOR) ? (IS_SET(DOOR->exit_info, EX_PICKPROOF) ? (IS_SET(DOOR->exit_info, EX_GDO) ? "Pickproof GDO" : "Pickproof") :
(IS_SET(DOOR->exit_info, EX_GDO) ? "Regular GDO" : "Regular Door")): "No door"), CCNRM(CH, C_CMP)); |
Scroll down a bit more. You'll see '/* For exit flags */'- replace the block immediately after this with:
Code: | void redit_disp_exit_flag_menu(struct descriptor_data * d)
{
send_to_char( "0) No door\r\n"
"1) Closeable door\r\n"
"2) Pickproof\r\n"
"3) Remote-Operation (GDO)\r\n"
"Enter choice:", CH);
} |
Now, down to ~1070. In the if-statement block under the 'doors are a bit idiotic' comment, add the following condition to the end:
Code: | else if (number == 3)
d->edit_room->dir_option[d->edit_number2]->exit_info = EX_ISDOOR | EX_PICKPROOF | EX_GDO; |
Now, go down to ~1240. Replace the 'door flags need special handling' code block with:
Code: | if (IS_SET(ptr->exit_info, EX_ISDOOR)) {
if (IS_SET(ptr->exit_info, EX_GDO)){
if (IS_SET(ptr->exit_info, EX_PICKPROOF))
temp_door_flag = 7;
else
temp_door_flag = 6;
}
else if (IS_SET(ptr->exit_info, EX_PICKPROOF))
temp_door_flag = 2;
else
temp_door_flag = 1;
} else
temp_door_flag = 0; |
Great! Now, go to DB.CPP. Scroll to ~986 and look for the if-elseif block concerning door flags. Replace it with:
Code: | if (flags == 1)
dir->exit_info = EX_ISDOOR;
else if (flags == 2)
dir->exit_info = EX_ISDOOR | EX_PICKPROOF;
else if (flags == 6)
dir->exit_info = EX_ISDOOR | EX_GDO;
else if (flags == 7)
dir->exit_info = EX_ISDOOR | EX_PICKPROOF | EX_GDO;
else
dir->exit_info = 0; |
Almost done! You still, however, need to make it so that the codebase knows what the hell you're talking about when you use the term 'GDO' in the code. Go to AWAKE.H and scroll to line ~512, at the bottom of the exit flag definition block. Add the following:
Code: | #define EX_GDO (1 << 6) /* exit is GDO-enabled */ |
And you're done! One GDO command, ready and waiting.
-----signature----- :::The Star Sapphire:::
|
Post Reply | Quote | Private Message
|
Title: Member
Posts: 274
Joined: 31 Mar 2007
|
Date Posted: Sun Mar 21, 2010 1:13 am
Subject:
|
The Peephole Add-On
Quote: | [5001] A studio apartment [ INDOORS, HOUSE, !RADIO]
WHY SHOULD KROOG CARE ABOUT YOUR PUNY MORTAL DESC
[ Exits: s(L) ]
<10P>
> l s
You see nothing special.
The door is closed.
Through the peephole, you see:
[5002] KROOG'S NEST OF DESPAIR [ INDOORS, ATRIUM, !RADIO]
KROOG HAS CLUB. KROOG INTRODUCE CLUB TO FACE.
[ Exits: n(L) e s(L) w ] |
This one's fast and simple. Go to ACT.INFORMATIVE.CPP and look at line ~1230, inside the LOOK_IN_DIRECTION function. At the end of the function, before the final }else, add this code:
Code: | if(ROOM_FLAGGED(ch->in_room, ROOM_HOUSE)){
/* Apartments have peepholes. That's just standard :D */
int original_loc = ch->in_room, targ_loc = EXIT(ch, dir)->to_room;
send_to_char("Through the peephole, you see:\r\n", ch);
char_from_room(ch);
char_to_room(ch, targ_loc);
look_at_room(ch, 0);
char_from_room(ch);
char_to_room(ch, original_loc);
} |
Characters can now use peepholes to look out from their own apartments.
-----signature----- :::The Star Sapphire:::
|
Post Reply | Quote | Private Message
|
Title: Member
Posts: 274
Joined: 31 Mar 2007
|
Date Posted: Mon Mar 22, 2010 10:48 pm
Subject:
|
Modifying the Steal command to require PK
As simple as they get. Go into ACT.OTHER.CPP and look for the do_steal ACMD set; look for the if-elseif block, and before the final else{ add:
Code: | else if (!PRF_FLAGGED(ch, PRF_PKER) || !PRF_FLAGGED(vict, PRF_PKER))
send_to_char(ch, "Both you and %s need to be toggled PK for that.", GET_NAME(vict)); |
-----signature----- :::The Star Sapphire:::
|
Post Reply | Quote | Private Message
|
Title: Member
Posts: 274
Joined: 31 Mar 2007
|
Date Posted: Tue Mar 23, 2010 6:41 pm
Subject: Date Edited: Wed Mar 31, 2010 6:07 am (edits total: 3) Edited By: Lucien
|
Addition of 'show' argument for Position
Quote: | > pos show
A Male Human is standing here, holding a sign that reads, "It works!". |
I've seen a few people interested in this command, so here you are: This command will show you what you look like to the rest of the room (barring any flags and tags).
In ACT.INFORMATIVE, after the blood block:
Code: | char *return_position_line(struct char_data * ch)
{
struct obj_data *obj = NULL;
if (IS_AFFECTED(ch, AFF_INVISIBLE))
strcpy(buf, "*");
else
*buf = '\0';
strcpy(buf, GET_NAME(ch));
if (!(GET_QUI(ch) > 0))
strcat(buf, " is here, seemingly paralyzed.");
else if (PLR_FLAGGED(ch, PLR_MATRIX))
strcat(buf, " is here, jacked into a cyberdeck.");
else if (PLR_FLAGGED(ch, PLR_REMOTE))
strcat(buf, " is here, jacked into a remote control deck.");
else if (AFF_FLAGGED(ch, AFF_DESIGN) || AFF_FLAGGED(ch, AFF_PROGRAM))
strcat(buf, " is here, typing away at a computer.");
else if (AFF_FLAGGED(ch, AFF_PART_DESIGN) || AFF_FLAGGED(ch, AFF_PART_BUILD))
strcat(buf, " is here, working on a cyberdeck.");
else if (AFF_FLAGGED(ch, AFF_SPELLDESIGN))
strcat(buf, " is here, working on a spell design.");
else if (AFF_FLAGGED(ch, AFF_CONJURE))
strcat(buf, " is here, performing a conjuring ritual.");
else if (AFF_FLAGGED(ch, AFF_LODGE))
strcat(buf, " is here, building a shamanic lodge.");
else if (AFF_FLAGGED(ch, AFF_CIRCLE))
strcat(buf, " is here, drawing a hermetic circle.");
else if (AFF_FLAGGED(ch, AFF_PACKING))
strcat(buf, " is here, working on a workshop.");
else if (AFF_FLAGGED(ch, AFF_BONDING))
strcat(buf, " is here, performing a bonding ritual.");
else if (AFF_FLAGGED(ch, AFF_PRONE))
strcat(buf, " is laying prone here.");
else if (AFF_FLAGGED(ch, AFF_PILOT))
{
if (AFF_FLAGGED(ch, AFF_RIG))
strcat(buf, " is plugged into the dashboard.");
else
strcat(buf, " is sitting in the drivers seat.");
} else if (AFF_FLAGGED(ch, AFF_MANNING))
{
for (obj = ch->in_veh->mount; obj; obj = obj->next_content)
if (obj->worn_by == ch)
break;
sprintf(buf, "%s is manning a %s.", buf, GET_OBJ_NAME(obj));
} else if (GET_POS(ch) != POS_FIGHTING)
{
strcat(buf, positions[(int) GET_POS(ch)]);
if (GET_DEFPOS(ch))
sprintf(buf2, ", %s.", GET_DEFPOS(ch));
else
sprintf(buf2, ".");
strcat(buf, buf2);
} else
{
if (FIGHTING(ch)) {
if (AFF_FLAGGED(ch, AFF_BANISH))
strcat(buf, " is here, attempting to banish ");
else
strcat(buf, " is here, fighting ");
if (FIGHTING(ch) == ch)
strcat(buf, "YOU! (what?)");
else {
if (ch->in_room == FIGHTING(ch)->in_room)
strcat(buf, PERS(FIGHTING(ch), ch));
else
strcat(buf, "someone in the distance");
strcat(buf, "!");
}
} else if (FIGHTING_VEH(ch)) {
strcat(buf, " is here, fighting ");
if ((ch->in_veh && ch->in_veh == FIGHTING_VEH(ch)) || (ch->char_specials.rigging && ch->char_specials.rigging == FIGHTING_VEH(ch)))
strcat(buf, "YOU!");
else {
if (ch->in_room == FIGHTING_VEH(ch)->in_room)
strcat(buf, GET_VEH_NAME(FIGHTING_VEH(ch)));
else
strcat(buf, "someone in the distance");
strcat(buf, "!");
}
} else /* NIL fighting pointer */
strcat(buf, " is here struggling with thin air.");
}
strcat(buf, "\r\n");
return buf;
} |
That's the actual meat of the code. Now, to modify the position command to accept the SHOW argument:
Around ~3360, you'll see the ACMD for do_position. In this ACMD, you'll find a line which reads:
Code: | if (GET_DEFPOS(ch))
delete [] GET_DEFPOS(ch);
GET_DEFPOS(ch) = str_dup(argument);
send_to_char(ch, "Position set.\r\n"); |
Insert the following code immediately before.
Code: | if(strcmp(str_dup(argument), "show") == 0){
send_to_char(return_position_line(ch), ch);
return;
}
if (GET_DEFPOS(ch))
delete [] GET_DEFPOS(ch);
int i;
char buffer[MAX_INPUT_LENGTH];
for(i = 0; i < strlen(argument) - 1; i++){
buffer[i] = argument[i];
}
if(ispunct(argument[i]) == 0){
buffer[i] = argument[i];
}
GET_DEFPOS(ch) = str_dup(buffer);
|
EDITS:
Fixed the meat of the show code to work properly.
-----signature----- :::The Star Sapphire:::
|
Post Reply | Quote | Private Message
|
Title: Member
Posts: 274
Joined: 31 Mar 2007
|
Date Posted: Tue Mar 23, 2010 7:02 pm
Subject:
|
Restoring the WizHelp command to .20:
Due to inoperative code or somesuch, the WizHelp command has been commented out of 20's release. Unfortunately, this leaves all new immortals completely in the dark as to their command list. To restore the command list, go to ACT.WIZARD and enter the ACMD(do_wizhelp) block.
Paste this at the start of the block:
Code: | struct char_data *vict = NULL;
int no, cmd_num;
if (!ch->desc)
return;
skip_spaces(&argument);
if (!*argument || ((vict = get_char_vis(ch, argument)) && !IS_NPC(vict) &&
access_level(vict, LVL_BUILDER))) {
if (!vict)
vict = ch;
sprintf(buf, "The following privileged commands are available to %s:\r\n",
vict == ch ? "you" : GET_CHAR_NAME(vict));
/* cmd_num starts at 1, not 0, to remove 'RESERVED' */
for (no = 1, cmd_num = 1; *cmd_info[cmd_num].command != '\n'; cmd_num++)
if (cmd_info[cmd_num].minimum_level >= LVL_BUILDER
&& GET_LEVEL(vict) >= cmd_info[cmd_num].minimum_level) {
sprintf(buf + strlen(buf), "%-13s", cmd_info[cmd_num].command);
if (!(no % 6))
strcat(buf, "\r\n");
no++;
}
strcat(buf, "\r\n");
send_to_char(buf, ch);
return;
}
|
(Note: Depending on your file, you may need to add another return; to the end of the block I pasted in.)
-----signature----- :::The Star Sapphire:::
|
Post Reply | Quote | Private Message
|
|
|
Awakened Worlds Forum Index » AwakeMUD Core Development |
|
All times are GMT Goto page 1, 2 Next
|
Page 1 of 2 |
|
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 can attach files in this forum You can download files in this forum
|
|
The time now is Mon Apr 23, 2018 7:16 pm
|
powered by hailBoards v.1.2.0 ©2006 SPIRE / [based on phpBB©]
|
| |