mirror of
https://github.com/tbamud/tbamud.git
synced 2026-03-29 16:37:21 +02:00
Add mcreate command
This commit is contained in:
parent
c1419f6fe7
commit
c6918a1d9c
6 changed files with 178 additions and 11 deletions
|
|
@ -17,7 +17,7 @@ Changes from stock tbaMUD 2025 to Cataclysm MUD v1.0.0-alpha:
|
|||
* Experience points and levels are removed in favor of skill based progression
|
||||
* Initial skills/spells based partly on tbaMUD code and 5e conversion (to be cleaned up in later release)
|
||||
* Expanded emoting system for roleplay
|
||||
* Permanent character death - aka. hardcore mode
|
||||
* Permanent character death
|
||||
* A hybrid "5e-like" system where:
|
||||
- [ ] Legacy THAC0 systems are removed in favor of the modern 5e system
|
||||
- [ ] Your skill level translates to a proficiency bonus on a per-skill level
|
||||
|
|
@ -65,6 +65,9 @@ Changes in v1.1.0-alpha:
|
|||
* Mounts added to help with long trips, and ability to use them as pack animals
|
||||
* Introduced AGENTS.md file to ensure code quality
|
||||
* Migration away from OLC with new commands "rcreate" and "rset" for builders to modify rooms
|
||||
* Migration away from OLC with new commands "ocreate", "oset", and "osave" for builders to modify objects
|
||||
* Migration away from OLC with new commands "mcreate" and "mset" for builders to modify NPC's
|
||||
* Fixed issue with msave not saving items in containers on NPC's
|
||||
|
||||
Features to be implemented in the next few releases:
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
int delete_mobile(mob_rnum);
|
||||
int copy_mobile(struct char_data *to, struct char_data *from);
|
||||
int add_mobile(struct char_data *, mob_vnum);
|
||||
void init_mobile(struct char_data *mob);
|
||||
int copy_mob_strings(struct char_data *to, struct char_data *from);
|
||||
int free_mob_strings(struct char_data *);
|
||||
int free_mobile(struct char_data *mob);
|
||||
|
|
|
|||
|
|
@ -212,6 +212,7 @@ cpp_extern const struct command_info cmd_info[] = {
|
|||
{ "medit" , "med" , POS_DEAD , do_oasis_medit, LVL_BUILDER, 0 },
|
||||
{ "mlist" , "mlist" , POS_DEAD , do_oasis_list, LVL_BUILDER, SCMD_OASIS_MLIST },
|
||||
{ "mcopy" , "mcopy" , POS_DEAD , do_oasis_copy, LVL_GOD, CON_MEDIT },
|
||||
{ "mcreate" , "mcreate" , POS_DEAD , do_mcreate , LVL_BUILDER, 0 },
|
||||
{ "msave" , "msav" , POS_DEAD , do_msave, LVL_BUILDER, 0 },
|
||||
{ "msgedit" , "msgedit" , POS_DEAD , do_msgedit, LVL_GOD, 0 },
|
||||
{ "mute" , "mute" , POS_DEAD , do_wizutil , LVL_GOD, SCMD_MUTE },
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
/* local functions */
|
||||
static void medit_setup_new(struct descriptor_data *d);
|
||||
static void init_mobile(struct char_data *mob);
|
||||
void init_mobile(struct char_data *mob);
|
||||
static void medit_save_to_disk(zone_vnum zone_num);
|
||||
static void medit_disp_positions(struct descriptor_data *d);
|
||||
static void medit_disp_sex(struct descriptor_data *d);
|
||||
|
|
@ -232,7 +232,7 @@ void medit_setup_existing(struct descriptor_data *d, int rmob_num)
|
|||
}
|
||||
|
||||
/* Ideally, this function should be in db.c, but I'll put it here for portability. */
|
||||
static void init_mobile(struct char_data *mob)
|
||||
void init_mobile(struct char_data *mob)
|
||||
{
|
||||
int i;
|
||||
clear_char(mob);
|
||||
|
|
|
|||
177
src/set.c
177
src/set.c
|
|
@ -2354,6 +2354,139 @@ static struct obj_data *find_obj_vnum_nearby(struct char_data *ch, obj_vnum vnum
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ACMD(do_mcreate)
|
||||
{
|
||||
char arg[MAX_INPUT_LENGTH];
|
||||
char buf[MAX_STRING_LENGTH];
|
||||
char namebuf[MAX_NAME_LENGTH];
|
||||
char timestr[64];
|
||||
struct char_data *newmob;
|
||||
struct char_data *mob;
|
||||
mob_vnum vnum;
|
||||
zone_rnum znum;
|
||||
time_t ct;
|
||||
|
||||
if (IS_NPC(ch) || ch->desc == NULL) {
|
||||
send_to_char(ch, "mcreate is only usable by connected players.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
one_argument(argument, arg);
|
||||
|
||||
if (!*arg) {
|
||||
send_to_char(ch,
|
||||
"Creates a new unfinished NPC which can be configured.\r\n"
|
||||
"\r\n"
|
||||
"Usage:\r\n"
|
||||
" mcreate <vnum>\r\n"
|
||||
"\r\n"
|
||||
"Examples:\r\n"
|
||||
" mcreate 1001\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_number(arg)) {
|
||||
send_to_char(ch,
|
||||
"Creates a new unfinished NPC which can be configured.\r\n"
|
||||
"\r\n"
|
||||
"Usage:\r\n"
|
||||
" mcreate <vnum>\r\n"
|
||||
"\r\n"
|
||||
"Examples:\r\n"
|
||||
" mcreate 1001\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
vnum = atoi(arg);
|
||||
if (vnum < IDXTYPE_MIN || vnum > IDXTYPE_MAX) {
|
||||
send_to_char(ch, "That mobile VNUM can't exist.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
znum = real_zone_by_thing(vnum);
|
||||
if (znum == NOWHERE) {
|
||||
send_to_char(ch, "Sorry, there is no zone for that number!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!can_edit_zone(ch, znum)) {
|
||||
send_cannot_edit(ch, zone_table[znum].number);
|
||||
return;
|
||||
}
|
||||
|
||||
if (real_mobile(vnum) != NOBODY) {
|
||||
mob = read_mobile(vnum, VIRTUAL);
|
||||
if (mob == NULL) {
|
||||
send_to_char(ch, "mcreate: failed to instantiate NPC %d.\r\n", vnum);
|
||||
return;
|
||||
}
|
||||
char_to_room(mob, IN_ROOM(ch));
|
||||
{
|
||||
const char *keyword = GET_KEYWORDS(mob);
|
||||
if (!keyword || !*keyword)
|
||||
keyword = "npc";
|
||||
if (!strn_cmp(keyword, "unfinished ", 11))
|
||||
keyword += 11;
|
||||
act("You form $t from clay.", FALSE, ch, (void *)keyword, 0, TO_CHAR);
|
||||
act("$n forms $t from clay.", TRUE, ch, (void *)keyword, 0, TO_ROOM);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CREATE(newmob, struct char_data, 1);
|
||||
init_mobile(newmob);
|
||||
|
||||
GET_LEVEL(newmob) = 1;
|
||||
|
||||
GET_NAME(newmob) = strdup("An unfinished NPC");
|
||||
GET_KEYWORDS(newmob) = strdup("unfinished npc");
|
||||
strlcpy(namebuf, GET_NAME(ch), sizeof(namebuf));
|
||||
snprintf(buf, sizeof(buf), "An unfinished NPC made by %.*s",
|
||||
(int)sizeof(namebuf) - 1, namebuf);
|
||||
GET_SDESC(newmob) = strdup(buf);
|
||||
snprintf(buf, sizeof(buf), "An unfinished NPC made by %.*s is here.\r\n",
|
||||
(int)sizeof(namebuf) - 1, namebuf);
|
||||
GET_LDESC(newmob) = strdup(buf);
|
||||
ct = time(0);
|
||||
strftime(timestr, sizeof(timestr), "%c", localtime(&ct));
|
||||
snprintf(buf, sizeof(buf),
|
||||
"An unfinished NPC made by %.*s on %.*s\r\n",
|
||||
(int)sizeof(namebuf) - 1, namebuf,
|
||||
(int)sizeof(timestr) - 1, timestr);
|
||||
GET_DDESC(newmob) = strdup(buf);
|
||||
GET_BACKGROUND(newmob) = strdup("No background has been recorded.\r\n");
|
||||
|
||||
if (add_mobile(newmob, vnum) == NOBODY) {
|
||||
free_mobile_strings(newmob);
|
||||
free(newmob);
|
||||
send_to_char(ch, "mcreate: failed to add NPC %d.\r\n", vnum);
|
||||
return;
|
||||
}
|
||||
|
||||
if (in_save_list(zone_table[znum].number, SL_MOB))
|
||||
remove_from_save_list(zone_table[znum].number, SL_MOB);
|
||||
|
||||
free_mobile_strings(newmob);
|
||||
free(newmob);
|
||||
|
||||
mob = read_mobile(vnum, VIRTUAL);
|
||||
if (mob == NULL) {
|
||||
send_to_char(ch, "mcreate: failed to instantiate NPC %d.\r\n", vnum);
|
||||
return;
|
||||
}
|
||||
|
||||
char_to_room(mob, IN_ROOM(ch));
|
||||
{
|
||||
const char *keyword = GET_KEYWORDS(mob);
|
||||
if (!keyword || !*keyword)
|
||||
keyword = "npc";
|
||||
if (!strn_cmp(keyword, "unfinished ", 11))
|
||||
keyword += 11;
|
||||
act("You create an unfinished $t from clay.", FALSE, ch, (void *)keyword, 0, TO_CHAR);
|
||||
act("$n forms an unfinished $t from clay.", TRUE, ch, (void *)keyword, 0, TO_ROOM);
|
||||
}
|
||||
}
|
||||
|
||||
ACMD(do_ocreate)
|
||||
{
|
||||
char arg[MAX_INPUT_LENGTH];
|
||||
|
|
@ -2403,11 +2536,6 @@ ACMD(do_ocreate)
|
|||
return;
|
||||
}
|
||||
|
||||
if (real_object(vnum) != NOTHING) {
|
||||
send_to_char(ch, "Object %d already exists.\r\n", vnum);
|
||||
return;
|
||||
}
|
||||
|
||||
znum = real_zone_by_thing(vnum);
|
||||
if (znum == NOWHERE) {
|
||||
send_to_char(ch, "Sorry, there is no zone for that number!\r\n");
|
||||
|
|
@ -2419,6 +2547,25 @@ ACMD(do_ocreate)
|
|||
return;
|
||||
}
|
||||
|
||||
if (real_object(vnum) != NOTHING) {
|
||||
obj = read_object(vnum, VIRTUAL);
|
||||
if (obj == NULL) {
|
||||
send_to_char(ch, "ocreate: failed to instantiate object %d.\r\n", vnum);
|
||||
return;
|
||||
}
|
||||
obj_to_char(obj, ch);
|
||||
{
|
||||
const char *sdesc = obj->short_description;
|
||||
if (!sdesc || !*sdesc)
|
||||
sdesc = obj->name;
|
||||
if (!sdesc || !*sdesc)
|
||||
sdesc = "object";
|
||||
act("You form $t from clay.", FALSE, ch, (void *)sdesc, 0, TO_CHAR);
|
||||
act("$n forms $t from clay.", TRUE, ch, (void *)sdesc, 0, TO_ROOM);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CREATE(newobj, struct obj_data, 1);
|
||||
clear_object(newobj);
|
||||
|
||||
|
|
@ -2454,9 +2601,23 @@ ACMD(do_ocreate)
|
|||
}
|
||||
|
||||
obj_to_char(obj, ch);
|
||||
send_to_char(ch,
|
||||
"Object %d created (temporary). Use osave to write it to disk.\r\n",
|
||||
vnum);
|
||||
{
|
||||
const char *sdesc = obj->short_description;
|
||||
if (!sdesc || !*sdesc)
|
||||
sdesc = obj->name;
|
||||
if (!sdesc || !*sdesc)
|
||||
sdesc = "object";
|
||||
if (!strn_cmp(sdesc, "an ", 3))
|
||||
sdesc += 3;
|
||||
else if (!strn_cmp(sdesc, "a ", 2))
|
||||
sdesc += 2;
|
||||
else if (!strn_cmp(sdesc, "the ", 4))
|
||||
sdesc += 4;
|
||||
if (!strn_cmp(sdesc, "unfinished ", 11))
|
||||
sdesc += 11;
|
||||
act("You create an unfinished $t from clay.", FALSE, ch, (void *)sdesc, 0, TO_CHAR);
|
||||
act("$n forms an unfinished $t from clay.", TRUE, ch, (void *)sdesc, 0, TO_ROOM);
|
||||
}
|
||||
}
|
||||
|
||||
ACMD(do_osave)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
ACMD(do_rset);
|
||||
ACMD(do_rcreate);
|
||||
ACMD(do_ocreate);
|
||||
ACMD(do_mcreate);
|
||||
ACMD(do_oset);
|
||||
ACMD(do_osave);
|
||||
ACMD(do_msave);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue