Welcome to the Builder Academy

Question Working remort snippet on my mud.

More
26 Jul 2025 23:50 #10839 by wlessard1
I do hope that you find this workable and useful.  I also hope I posted this properly.

Thanks to those who helped give me hints and suggestions despite my thick skull and being blind to them 
for a few posts.

If this helps someone else, I am glad I gave back some for all the snippets and code I have used and gotten help for over the years.
Code:
Here is my take on remorting. This code is for a single class remorting. I was inspired by the MUD Nukefire which I play a lot. While my mud is offline and just for my amusment alone, I feel passing on my take on remorts would be at least interesting and maybe might generate some laughter at least. First you want to make 2 files. remort.c remort.h not 100% I needed this one but. Also I include the banner, I hope I got that right. Remort.h /** * @file remort.h * This contains the headers and other functions possibly needed for remorting * I will improve the header for the whole file later to make sure I cover licensing. * Part of the core tbaMUD source code distribution, which is a derivative * of, and continuation of, CircleMUD. * * All rights reserved.  See license for complete information. * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991 */ #ifndef _REMORT_H_ #define _REMORT_H_ /* Constants for remort classes #define CLASS_MAGIC_USER    0 #define CLASS_CLERIC        1 #define CLASS_THIEF         2 #define CLASS_WARRIOR       3 #define CLASS_BARD          4 */ /* Function prototypes */ void do_remort(struct char_data *ch, char *argument, int cmd, int subcmd); void do_remort_start(struct char_data *ch); /*void assign_remort_skills(struct char_data *ch, int remort_level);*/ #endif /* _REMORT_H_ */ Remort.c I added a bunch of debug lines to check and make sure things were doing what I wanted properly. My mud has 51 levels of mortal. #include "conf.h" #include "sysdep.h" #include "structs.h" #include "utils.h" #include "comm.h" #include "interpreter.h" #include "handler.h" #include "db.h" #include "remort.h" #include "spells.h" extern const char *class_menu; int parse_class(char arg); void do_remort_start(struct char_data *ch); ACMD(do_remort) { char arg[MAX_STRING_LENGTH]; char buf[MAX_INPUT_LENGTH]; if(GET_LEVEL(ch) < 51 || GET_LEVEL(ch) > 51){ send_to_char(ch, "You cannot remort at this time!"); return; } one_argument(argument, arg); if(GET_REMORT_LEVEL(ch) < 20) { switch(*arg) { case 'n': case 'N': send_to_char(ch, "\r\nYour not going to remort at this time?"); send_to_char(ch, "\r\nThe immortals have allowed you to stay at your level");     break; case 'y': case 'Y': send_to_char(ch, "\r\nCongrulations!"); send_to_char(ch, "\r\nYou have decided to remort!"); send_to_char(ch, "\r\nYou are now leaving you old body, to start a new!"); send_to_char(ch, "\r\nA new journey has begun for you!\r\n"); GET_LEVEL(ch) = 1; log("DEBUG: Setting remort level for %s to %d", GET_NAME(ch), GET_REMORT_LEVEL(ch) + 1); GET_REMORT_LEVEL(ch) = GET_REMORT_LEVEL(ch) + 1;         if (GET_REMORT_LEVEL(ch) == 1)         ch->points.max_hit = 100 + (GET_REMORT_LEVEL(ch) * 50); ch->points.max_mana = 100 + (GET_REMORT_LEVEL(ch) * 50); ch->points.max_move = 100 + (GET_REMORT_LEVEL(ch) * 50); ch->points.hit = 100; ch->points.mana = 100; ch->points.move = 100; ch->points.exp = 1;     do_remort_start(ch); log("DEBUG: Saving character %s after remort", GET_NAME(ch)); save_char(ch); sprintf(buf, "%s has remorted to level 1.", GET_NAME(ch)); /* mudlog(buf, NRM, MAX(LVL_IMMORT, GET_INVIS_LEV(ch)), TRUE); TEMP REMOVAL */ break; default:     send_to_char(ch, "\r\n(type: \"remort y\" if u DO OR \"remort n\" if you DON'T!"); send_to_char(ch, "\r\nAre you sure you want to remort: "); return;    }    } else {    send_to_char(ch, "\r\nYou can't remort anymore!");    send_to_char(ch, "\r\nContact Management if you need help!");    } } void do_remort_start(struct char_data *ch) {   /* Debug: Confirm do_remort_start is called */   log("DEBUG: do_remort_start called for %s (class: %d, remort level: %d)", GET_NAME(ch), GET_CLASS(ch), GET_REMORT_LEVEL(ch));   /* Increment remort level   GET_REMORT_LEVEL(ch)++; */   /* Initialize based on do_start */   set_title(ch, NULL);   GET_LEVEL(ch) = 1;   GET_EXP(ch) = 1;   /* Set stats (minimal, to be adjusted in class.c or elsewhere) */   GET_MAX_HIT(ch) = 100 + (GET_REMORT_LEVEL(ch) * 50);   GET_MAX_MANA(ch) = 100 + (GET_REMORT_LEVEL(ch) * 50);   GET_MAX_MOVE(ch) = 100 + (GET_REMORT_LEVEL(ch) * 50);   GET_HIT(ch) = GET_MAX_HIT(ch);   GET_MANA(ch) = GET_MAX_MANA(ch);   GET_MOVE(ch) = GET_MAX_MOVE(ch);   /* Assign class-specific skills and bonuses */   switch (GET_CLASS(ch)) {     case CLASS_CLERIC:       log("DEBUG: No skills or bonuses assigned for %s (Cleric, remort level: %d)", GET_NAME(ch), GET_REMORT_LEVEL(ch));       break;     case CLASS_MAGIC_USER:       log("DEBUG: No skills or bonuses assigned for %s (Magic User, remort level: %d)", GET_NAME(ch), GET_REMORT_LEVEL(ch));       break;     case CLASS_THIEF:       log("DEBUG: No skills or bonuses assigned for %s (Thief, remort level: %d)", GET_NAME(ch), GET_REMORT_LEVEL(ch));       break;     case CLASS_WARRIOR:       if (GET_REMORT_LEVEL(ch) == 1) {         /* Skills */         if (GET_SKILL(ch, SKILL_SNEAK) == 0) {           SET_SKILL(ch, SKILL_SNEAK, 10); /* Remort level 1 skill */           log("DEBUG: Assigned SNEAK to %s (Warrior): SNEAK=%d", GET_NAME(ch), GET_SKILL(ch, SKILL_SNEAK));         } else {           log("DEBUG: Preserved SNEAK at %d for %s (Warrior)", GET_SKILL(ch, SKILL_SNEAK), GET_NAME(ch));         }         /* Bonuses */         GET_AC(ch) += -10; /* Improved AC (lower is better in tbaMUD) */         GET_HITROLL(ch) += 1; /* +1 hit roll */         GET_DAMROLL(ch) += 1; /* +1 damage roll */         log("DEBUG: Warrior remort 1 bonuses for %s: AC=%d, HITROLL=%d, DAMROLL=%d", GET_NAME(ch), GET_AC(ch), GET_HITROLL(ch), GET_DAMROLL(ch));       } else if (GET_REMORT_LEVEL(ch) == 2) {         /* Skills */         if (GET_SKILL(ch, SPELL_IDENTIFY) == 0) {           SET_SKILL(ch, SPELL_IDENTIFY, 10); /* Remort level 2 skill */           log("DEBUG: Assigned SPELL_IDENTIFY to %s (Warrior): IDENTIFY=%d", GET_NAME(ch), GET_SKILL(ch, SPELL_IDENTIFY));         } else {           log("DEBUG: Preserved SPELL_IDENTIFY at %d for %s (Warrior)", GET_SKILL(ch, SPELL_IDENTIFY), GET_NAME(ch));         }         /* Bonuses */         GET_AC(ch) += -15; /* Further AC improvement */         GET_HITROLL(ch) += 2; /* +2 hit roll */         GET_DAMROLL(ch) += 2; /* +2 damage roll */         log("DEBUG: Warrior remort 2 bonuses for %s: AC=%d, HITROLL=%d, DAMROLL=%d", GET_NAME(ch), GET_AC(ch), GET_HITROLL(ch), GET_DAMROLL(ch));       } else if (GET_REMORT_LEVEL(ch) == 3) {         /* Skills */         if (GET_SKILL(ch, SKILL_KICK) == 0) {           SET_SKILL(ch, SKILL_KICK, 10); /* Remort level 3 skill */           log("DEBUG: Assigned KICK to %s (Warrior): KICK=%d", GET_NAME(ch), GET_SKILL(ch, SKILL_KICK));         } else {           log("DEBUG: Preserved KICK at %d for %s (Warrior)", GET_SKILL(ch, SKILL_KICK), GET_NAME(ch));         }         /* Bonuses */         GET_AC(ch) += -20; /* Further AC improvement */         GET_HITROLL(ch) += 3; /* +3 hit roll */         GET_DAMROLL(ch) += 3; /* +3 damage roll */         log("DEBUG: Warrior remort 3 bonuses for %s: AC=%d, HITROLL=%d, DAMROLL=%d", GET_NAME(ch), GET_AC(ch), GET_HITROLL(ch), GET_DAMROLL(ch));       }       break;     case CLASS_BARD:       log("DEBUG: No skills or bonuses assigned for %s (Bard, remort level: %d)", GET_NAME(ch), GET_REMORT_LEVEL(ch));       break;     default:       log("DEBUG: No skills or bonuses assigned for %s (unknown class: %d)", GET_NAME(ch), GET_CLASS(ch));       break;   }   /* Set conditions (drunk can be 0, no hunger/thirst I don't like hunger and thirst, adjust as you see fit) */   GET_COND(ch, THIRST) = -1;   GET_COND(ch, HUNGER) = -1;   GET_COND(ch, DRUNK) = 0;   /* Save character */   save_char(ch);   } PFDEFAULTS.H Around line 20 in stock tbamud add this. #define PFDEF_REMORT_LEVEL  0 In Players.c Around line 258 in load_char     GET_REMORT_LEVEL(ch) = PFDEF_REMORT_LEVEL; around line 440 in load_char else if(!strcmp(tag, "Rmlv"))   GET_REMORT_LEVEL(ch) = atoi(line);   Around line  588 this is in function void save_char     if (GET_REMORT_LEVEL(ch) != PFDEF_REMORT_LEVEL) fprintf(fl, "Rmlv: %d\n", GET_REMORT_LEVEL(ch)); Also in save_char around line 734   /* Update Remort Level in player index */     if (player_table[id].rmvl != GET_REMORT_LEVEL(ch)) {       save_index = TRUE;       player_table[id].rmvl = GET_REMORT_LEVEL(ch);             spec_procs.c I fought the code for so long to get this right I am putting in the whole Void List_skills function void list_skills(struct char_data *ch) {   const char *overflow = "\r\n**OVERFLOW**\r\n";   int i, sortpos, ret;   size_t len = 0;   char buf2[MAX_STRING_LENGTH];   len = snprintf(buf2, sizeof(buf2), "You have %d practice session%s remaining.\r\n"     "You know of the following %ss:\r\n", GET_PRACTICES(ch),     GET_PRACTICES(ch) == 1 ? "" : "s", SPLSKL(ch));   for (sortpos = 1; sortpos <= MAX_SKILLS; sortpos++) {     i = spell_sort_info[sortpos];     if (strcmp(spell_info[i].name, unused_spellname) != 0 &&       ((GET_LEVEL(ch) >= spell_info[i].min_level[(int) GET_CLASS(ch)]) ||        (GET_REMORT_LEVEL(ch) > 0 && GET_SKILL(ch, i) > 0))) {       ret = snprintf(buf2 + len, sizeof(buf2) - len, "%-20s %s\r\n", spell_info[i].name, how_good(GET_SKILL(ch, i)));       if (ret < 0 || len + ret >= sizeof(buf2))         break;       len += ret;     }   }   if (len >= sizeof(buf2))     strcpy(buf2 + sizeof(buf2) - strlen(overflow) - 1, overflow); /* strcpy: OK */   page_string(ch->desc, buf2, TRUE); } act.informative.c I set my current remort to allow for 20 remort levels. In ACMD Do_who Just above "if (GET_INVIS_LEV(tch))         if (GET_REMORT_LEVEL(tch) == 1)       strcat(buf, " (teir)");     if (GET_REMORT_LEVEL(tch) == 2)       strcat(buf, " (hero)");     if (GET_REMORT_LEVEL(tch) == 3)       strcat(buf, " (avatar)");     if (GET_REMORT_LEVEL(tch) == 4)       strcat(buf, " (high mortal)"); act.wizard.c You might not have this so skip. Function do_stat_mortal send_to_char(ch, "Name: %s, Level: %2d %s %s Remort Level: %d\r\n", GET_NAME(ch), GET_LEVEL(ch), buf1, buf2, GET_REMORT_LEVEL(ch)); further down in do_advance   } else if (oldlevel < LVL_IMMORT && newlevel >= LVL_IMMORT && GET_REMORT_LEVEL(victim) == 0) {     Next in class.c In function do_start First two lines are for location   GET_LEVEL(ch) = 1;   GET_EXP(ch) = 10801;   GET_REMORT_LEVEL(ch) = 0; /* remort snippet bramage */ in Do_advance I put what I wanted for stat progression switch (GET_CLASS(ch)) {   case CLASS_MAGIC_USER:     add_hp += rand_number(10, 20) + (int)(GET_REMORT_LEVEL(ch) * 50);     add_mana = rand_number(GET_LEVEL(ch), (int)(5 * GET_LEVEL(ch))) + (int)(GET_REMORT_LEVEL(ch) * 50);     add_move = rand_number(10, 20);     break;   case CLASS_CLERIC:     add_hp += rand_number(10, 20) + (int)(GET_REMORT_LEVEL(ch) * 50);     add_mana = rand_number(GET_LEVEL(ch), (int)(5 * GET_LEVEL(ch))) + (int)(GET_REMORT_LEVEL(ch) * 50);     add_move = rand_number(10, 20);     break;   case CLASS_THIEF:     add_hp += rand_number(10, 20) + (int)(GET_REMORT_LEVEL(ch) * 50);     add_mana = 5;     add_move = rand_number(10, 20);     break;   case CLASS_WARRIOR:     add_hp += rand_number(10, 20) + (int)(GET_REMORT_LEVEL(ch) * 50);     add_mana = 5;     add_move = rand_number(10, 20);     break;   case CLASS_BARD:     add_hp += rand_number(10, 20) + (int)(GET_REMORT_LEVEL(ch) * 50);     add_mana = rand_number(GET_LEVEL(ch), (int)(5 * GET_LEVEL(ch))) + (int)(GET_REMORT_LEVEL(ch) * 25);     add_move = rand_number(10, 20);     break;   } Next in iterpreter.c Set remort for max level mortal. { "remort"       , "remort"   , POS_STANDING , do_remort      , 51, 0 }, /* Remort Snippet Bramage */   in Do_score I removed do_score a while back into its own file But this is the change. Make sure where ever your do_score is you also have #include "remort.h" in the actual function   send_to_char(ch, "Level: %d  Remort Level: %d\r\n", GET_LEVEL(ch), GET_REMORT_LEVEL(ch));     In act.h around line 337   ACMD(do_remort); /* Remort snippet bramage */ In structs.h in player_special_data_saved   int remort_level;             /**< Remort Level snippet Bramage */     now the last one...   in utils.h around line 577     #define GET_REMORT_LEVEL(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.remort_level)) This should be it, I do not take any responsibilty for code issues. This works just about perfectly on my mud. I do not have a player load as I am the only player so I do not know how it fairs This works. It  gives skills/spells to players and even bonuses to different abilities. I am testing what I can give a player and what I cant I only filled the Warrior remort levels for now because I am still testing how far I can go with it and it still works. I haven't broken it yet. I also make no claims on how this would work in a multiclass situation. I hope I have made sure I have all the pieces I used in here for you if you choose to use it.

Please Log in or Create an account to join the conversation.

Time to create page: 0.517 seconds