mirror of
https://github.com/tbamud/tbamud.git
synced 2025-09-21 21:40:49 +02:00
New Group System, Room Events, and Event System Efficiency Upgrade... and a couple bug fixes.
This commit is contained in:
parent
82da0e8063
commit
a2aaab144f
32 changed files with 612 additions and 322 deletions
|
@ -2,11 +2,13 @@ TbaMUD is currently being developed by The Builder Academy. If you need any
|
|||
help, find any bugs, or have ideas for improvement please stop by TBA at
|
||||
telnet://tbamud.com:9091 or email rumble@tbamud.com --Rumble
|
||||
@
|
||||
[Feb 12 2013] - Vatiken
|
||||
feature: New group system.
|
||||
feature: Room events.
|
||||
bug: Many small bug fixes.
|
||||
[Sep 08 2012] - Rumble
|
||||
added another example to doc/syserr.txt
|
||||
Added a !NPC check to can_take_object. It was spamming a "mob using player data SYSERR". This means mobs do not have a max weight carrying capacity anymore. I think this is a good thing because I've seen people stumped when mob triggers fail due to weight limitations. But it could be unbalancing on some MUDs since pets could then carry unlimited gear.
|
||||
ht limitations. But it could be unbalancing on some MUDs since pets could then carry unlimited gear.
|
||||
Uncommented code to prevent crashes when trying to save a deleted object.
|
||||
[Aug 22 2012] - Rumble
|
||||
bug: moved cedit load_config of no_mort_to_immort to its proper place. (thanks Liko)
|
||||
[Aug 12 2012] - Vatiken
|
||||
|
|
|
@ -73,41 +73,26 @@ ACMD(do_say)
|
|||
|
||||
ACMD(do_gsay)
|
||||
{
|
||||
struct char_data *k;
|
||||
struct follow_type *f;
|
||||
|
||||
skip_spaces(&argument);
|
||||
|
||||
if (!AFF_FLAGGED(ch, AFF_GROUP)) {
|
||||
send_to_char(ch, "But you are not the member of a group!\r\n");
|
||||
|
||||
if (!GROUP(ch)) {
|
||||
send_to_char(ch, "But you are not a member of a group!\r\n");
|
||||
return;
|
||||
}
|
||||
if (!*argument)
|
||||
send_to_char(ch, "Yes, but WHAT do you want to group-say?\r\n");
|
||||
else {
|
||||
char buf[MAX_STRING_LENGTH];
|
||||
|
||||
|
||||
if (CONFIG_SPECIAL_IN_COMM && legal_communication(argument))
|
||||
parse_at(argument);
|
||||
|
||||
if (ch->master)
|
||||
k = ch->master;
|
||||
else
|
||||
k = ch;
|
||||
|
||||
snprintf(buf, sizeof(buf), "$n tells the group, '%s\tn'", argument);
|
||||
|
||||
if (AFF_FLAGGED(k, AFF_GROUP) && (k != ch))
|
||||
act(buf, FALSE, ch, 0, k, TO_VICT | TO_SLEEP);
|
||||
for (f = k->followers; f; f = f->next)
|
||||
if (AFF_FLAGGED(f->follower, AFF_GROUP) && (f->follower != ch))
|
||||
act(buf, FALSE, ch, 0, f->follower, TO_VICT | TO_SLEEP);
|
||||
|
||||
parse_at(argument);
|
||||
|
||||
send_to_group(ch, ch->group, "%s%s%s says, '%s'%s\r\n", CCGRN(ch, C_NRM), CCGRN(ch, C_NRM), GET_NAME(ch), argument, CCNRM(ch, C_NRM));
|
||||
|
||||
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_NOREPEAT))
|
||||
send_to_char(ch, "%s", CONFIG_OK);
|
||||
else
|
||||
send_to_char(ch, "You tell the group, '%s\tn'\r\n", argument);
|
||||
}
|
||||
send_to_char(ch, "%sYou group-say, '%s'%s\r\n", CCGRN(ch, C_NRM), argument, CCNRM(ch, C_NRM));
|
||||
}
|
||||
}
|
||||
|
||||
static void perform_tell(struct char_data *ch, struct char_data *vict, char *arg)
|
||||
|
|
|
@ -249,7 +249,6 @@ ACMD(do_sneak);
|
|||
ACMD(do_split);
|
||||
ACMD(do_steal);
|
||||
ACMD(do_title);
|
||||
ACMD(do_ungroup);
|
||||
ACMD(do_visible);
|
||||
|
||||
|
||||
|
@ -328,6 +327,7 @@ ACMD(do_plist);
|
|||
ACMD(do_purge);
|
||||
ACMD(do_recent);
|
||||
ACMD(do_restore);
|
||||
void return_to_char(struct char_data * ch);
|
||||
ACMD(do_return);
|
||||
ACMD(do_saveall);
|
||||
ACMD(do_send);
|
||||
|
|
|
@ -309,6 +309,17 @@ static void list_one_char(struct char_data *i, struct char_data *ch)
|
|||
}
|
||||
}
|
||||
|
||||
if (GROUP(i)) {
|
||||
if (GROUP(i) == GROUP(ch))
|
||||
send_to_char(ch, "(%s%s%s) ", CBGRN(ch, C_NRM),
|
||||
GROUP_LEADER(GROUP(i)) == i ? "leader" : "group",
|
||||
CCNRM(ch, C_NRM));
|
||||
else
|
||||
send_to_char(ch, "(%s%s%s) ", CBRED(ch, C_NRM),
|
||||
GROUP_LEADER(GROUP(i)) == i ? "leader" : "group",
|
||||
CCNRM(ch, C_NRM));
|
||||
}
|
||||
|
||||
if (IS_NPC(i) && i->player.long_descr && GET_POS(i) == GET_DEFAULT_POS(i)) {
|
||||
if (AFF_FLAGGED(i, AFF_INVISIBLE))
|
||||
send_to_char(ch, "*");
|
||||
|
@ -1201,9 +1212,9 @@ ACMD(do_who)
|
|||
continue;
|
||||
if (showclass && !(showclass & (1 << GET_CLASS(tch))))
|
||||
continue;
|
||||
if (showgroup && (!tch->master || !AFF_FLAGGED(tch, AFF_GROUP)))
|
||||
if (showgroup && !GROUP(tch))
|
||||
continue;
|
||||
if (showleader && (!tch->followers || !AFF_FLAGGED(tch, AFF_GROUP)))
|
||||
if (showleader && (!GROUP(tch) || GROUP_LEADER(GROUP(tch)) != tch))
|
||||
continue;
|
||||
for (i = 0; *rank[i].disp != '\n'; i++)
|
||||
if (GET_LEVEL(tch) >= rank[i].min_level && GET_LEVEL(tch) <= rank[i].max_level)
|
||||
|
@ -1245,9 +1256,9 @@ ACMD(do_who)
|
|||
continue;
|
||||
if (showclass && !(showclass & (1 << GET_CLASS(tch))))
|
||||
continue;
|
||||
if (showgroup && (!tch->master || !AFF_FLAGGED(tch, AFF_GROUP)))
|
||||
if (showgroup && !GROUP(tch))
|
||||
continue;
|
||||
if (showleader && (!tch->followers || !AFF_FLAGGED(tch, AFF_GROUP)))
|
||||
if (showleader && (!GROUP(tch) || GROUP_LEADER(GROUP(tch)) != tch))
|
||||
continue;
|
||||
|
||||
if (short_list) {
|
||||
|
|
|
@ -965,7 +965,7 @@ ACMD(do_follow)
|
|||
}
|
||||
if (ch->master)
|
||||
stop_follower(ch);
|
||||
REMOVE_BIT_AR(AFF_FLAGS(ch), AFF_GROUP);
|
||||
|
||||
add_follower(ch, leader);
|
||||
}
|
||||
}
|
||||
|
|
308
src/act.other.c
308
src/act.other.c
|
@ -35,9 +35,8 @@
|
|||
|
||||
/* Local defined utility functions */
|
||||
/* do_group utility functions */
|
||||
static int perform_group(struct char_data *ch, struct char_data *vict);
|
||||
static void print_group(struct char_data *ch);
|
||||
|
||||
static void display_group_list(struct char_data * ch);
|
||||
|
||||
ACMD(do_quit)
|
||||
{
|
||||
|
@ -319,185 +318,172 @@ ACMD(do_title)
|
|||
}
|
||||
}
|
||||
|
||||
static int perform_group(struct char_data *ch, struct char_data *vict)
|
||||
{
|
||||
if (AFF_FLAGGED(vict, AFF_GROUP) || !CAN_SEE(ch, vict))
|
||||
return (0);
|
||||
|
||||
SET_BIT_AR(AFF_FLAGS(vict), AFF_GROUP);
|
||||
if (ch != vict)
|
||||
act("$N is now a member of your group.", FALSE, ch, 0, vict, TO_CHAR);
|
||||
act("You are now a member of $n's group.", FALSE, ch, 0, vict, TO_VICT);
|
||||
act("$N is now a member of $n's group.", FALSE, ch, 0, vict, TO_NOTVICT);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void print_group(struct char_data *ch)
|
||||
{
|
||||
struct char_data *k;
|
||||
struct follow_type *f;
|
||||
struct char_data * k;
|
||||
|
||||
if (!AFF_FLAGGED(ch, AFF_GROUP))
|
||||
send_to_char(ch, "But you are not the member of a group!\r\n");
|
||||
else {
|
||||
char buf[MAX_STRING_LENGTH];
|
||||
send_to_char(ch, "Your group consists of:\r\n");
|
||||
|
||||
send_to_char(ch, "Your group consists of:\r\n");
|
||||
|
||||
k = (ch->master ? ch->master : ch);
|
||||
|
||||
if (AFF_FLAGGED(k, AFF_GROUP)) {
|
||||
snprintf(buf, sizeof(buf), " [%3dH %3dM %3dV] [%2d %s] $N (Head of group)",
|
||||
GET_HIT(k), GET_MANA(k), GET_MOVE(k), GET_LEVEL(k), CLASS_ABBR(k));
|
||||
act(buf, FALSE, ch, 0, k, TO_CHAR);
|
||||
}
|
||||
|
||||
for (f = k->followers; f; f = f->next) {
|
||||
if (!AFF_FLAGGED(f->follower, AFF_GROUP))
|
||||
continue;
|
||||
|
||||
snprintf(buf, sizeof(buf), " [%3dH %3dM %3dV] [%2d %s] $N", GET_HIT(f->follower),
|
||||
GET_MANA(f->follower), GET_MOVE(f->follower),
|
||||
GET_LEVEL(f->follower), CLASS_ABBR(f->follower));
|
||||
act(buf, FALSE, ch, 0, f->follower, TO_CHAR);
|
||||
}
|
||||
}
|
||||
while ((k = (struct char_data *) simple_list(ch->group->members)) != NULL)
|
||||
send_to_char(ch, "%-*s: %s[%4d/%-4d]H [%4d/%-4d]M [%4d/%-4d]V%s\r\n",
|
||||
count_color_chars(GET_NAME(k))+22, GET_NAME(k),
|
||||
GROUP_LEADER(GROUP(ch)) == k ? CBGRN(ch, C_NRM) : CCGRN(ch, C_NRM),
|
||||
GET_HIT(k), GET_MAX_HIT(k),
|
||||
GET_MANA(k), GET_MAX_MANA(k),
|
||||
GET_MOVE(k), GET_MAX_MOVE(k),
|
||||
CCNRM(ch, C_NRM));
|
||||
}
|
||||
|
||||
static void display_group_list(struct char_data * ch)
|
||||
{
|
||||
struct group_data * group;
|
||||
int count = 0;
|
||||
|
||||
if (group_list->iSize) {
|
||||
send_to_char(ch, "# Group Leader # of Members In Zone\r\n"
|
||||
"---------------------------------------------------\r\n");
|
||||
|
||||
while ((group = (struct group_data *) simple_list(group_list)) != NULL) {
|
||||
if (IS_SET(GROUP_FLAGS(group), GROUP_NPC))
|
||||
continue;
|
||||
if (GROUP_LEADER(group) && !IS_SET(GROUP_FLAGS(group), GROUP_ANON))
|
||||
send_to_char(ch, "%-2d) %s%-12s %-2d %s%s\r\n",
|
||||
++count,
|
||||
IS_SET(GROUP_FLAGS(group), GROUP_OPEN) ? CCGRN(ch, C_NRM) : CCRED(ch, C_NRM),
|
||||
GET_NAME(GROUP_LEADER(group)), group->members->iSize, zone_table[world[IN_ROOM(GROUP_LEADER(group))].zone].name,
|
||||
CCNRM(ch, C_NRM));
|
||||
else
|
||||
send_to_char(ch, "%-2d) Hidden\r\n", ++count);
|
||||
|
||||
}
|
||||
}
|
||||
if (count)
|
||||
send_to_char(ch, "\r\n"
|
||||
"%sSeeking Members%s\r\n"
|
||||
"%sClosed%s\r\n",
|
||||
CCGRN(ch, C_NRM), CCNRM(ch, C_NRM),
|
||||
CCRED(ch, C_NRM), CCNRM(ch, C_NRM));
|
||||
else
|
||||
send_to_char(ch, "\r\n"
|
||||
"Currently no groups formed.\r\n");
|
||||
}
|
||||
|
||||
/* Vatiken's Group System: Version 1.1 */
|
||||
ACMD(do_group)
|
||||
{
|
||||
char buf[MAX_STRING_LENGTH];
|
||||
struct char_data *vict;
|
||||
struct follow_type *f;
|
||||
int found;
|
||||
|
||||
one_argument(argument, buf);
|
||||
argument = one_argument(argument, buf);
|
||||
|
||||
if (!*buf) {
|
||||
print_group(ch);
|
||||
if (GROUP(ch))
|
||||
print_group(ch);
|
||||
else
|
||||
send_to_char(ch, "You must specify a group option, or type HELP GROUP for more info.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ch->master) {
|
||||
act("You cannot enroll group members without being head of a group.",
|
||||
FALSE, ch, 0, 0, TO_CHAR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!str_cmp(buf, "all")) {
|
||||
perform_group(ch, ch);
|
||||
for (found = 0, f = ch->followers; f; f = f->next)
|
||||
found += perform_group(ch, f->follower);
|
||||
if (!found)
|
||||
send_to_char(ch, "Everyone following you is already in your group.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(vict = get_char_vis(ch, buf, NULL, FIND_CHAR_ROOM)))
|
||||
send_to_char(ch, "%s", CONFIG_NOPERSON);
|
||||
else if ((vict->master != ch) && (vict != ch))
|
||||
act("$N must follow you to enter your group.", FALSE, ch, 0, vict, TO_CHAR);
|
||||
else {
|
||||
if (!AFF_FLAGGED(vict, AFF_GROUP))
|
||||
perform_group(ch, vict);
|
||||
else {
|
||||
if (ch != vict)
|
||||
act("$N is no longer a member of your group.", FALSE, ch, 0, vict, TO_CHAR);
|
||||
act("You have been kicked out of $n's group!", FALSE, ch, 0, vict, TO_VICT);
|
||||
act("$N has been kicked out of $n's group!", FALSE, ch, 0, vict, TO_NOTVICT);
|
||||
REMOVE_BIT_AR(AFF_FLAGS(vict), AFF_GROUP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ACMD(do_ungroup)
|
||||
{
|
||||
char buf[MAX_INPUT_LENGTH];
|
||||
struct follow_type *f, *next_fol;
|
||||
struct char_data *tch;
|
||||
|
||||
one_argument(argument, buf);
|
||||
|
||||
if (!*buf) {
|
||||
if (ch->master || !(AFF_FLAGGED(ch, AFF_GROUP))) {
|
||||
send_to_char(ch, "But you lead no group!\r\n");
|
||||
|
||||
if (is_abbrev(buf, "new")) {
|
||||
if (GROUP(ch))
|
||||
send_to_char(ch, "You are already in a group.\r\n");
|
||||
else
|
||||
create_group(ch);
|
||||
} else if (is_abbrev(buf, "list"))
|
||||
display_group_list(ch);
|
||||
else if (is_abbrev(buf, "join")) {
|
||||
skip_spaces(&argument);
|
||||
if (!(vict = get_char_vis(ch, argument, NULL, FIND_CHAR_ROOM))) {
|
||||
send_to_char(ch, "Join who?\r\n");
|
||||
return;
|
||||
} else if (vict == ch) {
|
||||
send_to_char(ch, "That would be one lonely grouping.\r\n");
|
||||
return;
|
||||
} else if (GROUP(ch)) {
|
||||
send_to_char(ch, "But you are already part of a group.\r\n");
|
||||
return;
|
||||
} else if (!GROUP(vict)) {
|
||||
send_to_char(ch, "They are not a part of a group!\r\n");
|
||||
return;
|
||||
} else if (!IS_SET(GROUP_FLAGS(GROUP(vict)), GROUP_OPEN)) {
|
||||
send_to_char(ch, "That group isn't accepting members.\r\n");
|
||||
return;
|
||||
}
|
||||
join_group(ch, GROUP(vict));
|
||||
} else if (is_abbrev(buf, "kick")) {
|
||||
skip_spaces(&argument);
|
||||
if (!(vict = get_char_vis(ch, argument, NULL, FIND_CHAR_ROOM))) {
|
||||
send_to_char(ch, "Kick out who?\r\n");
|
||||
return;
|
||||
} else if (vict == ch) {
|
||||
send_to_char(ch, "There are easier ways to leave the group.\r\n");
|
||||
return;
|
||||
} else if (!GROUP(ch) ) {
|
||||
send_to_char(ch, "But you are not part of a group.\r\n");
|
||||
return;
|
||||
} else if (GROUP_LEADER(GROUP(ch)) != ch ) {
|
||||
send_to_char(ch, "Only the group's leader can kick members out.\r\n");
|
||||
return;
|
||||
} else if (GROUP(vict) != GROUP(ch)) {
|
||||
send_to_char(ch, "They are not a member of your group!\r\n");
|
||||
return;
|
||||
}
|
||||
send_to_char(ch, "You have kicked %s out of the group.\r\n", GET_NAME(vict));
|
||||
send_to_char(vict, "You have been kicked out of the group.\r\n");
|
||||
leave_group(vict);
|
||||
} else if (is_abbrev(buf, "leave")) {
|
||||
if (!GROUP(ch)) {
|
||||
send_to_char(ch, "But you aren't apart of a group!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (f = ch->followers; f; f = next_fol) {
|
||||
next_fol = f->next;
|
||||
if (AFF_FLAGGED(f->follower, AFF_GROUP)) {
|
||||
REMOVE_BIT_AR(AFF_FLAGS(f->follower), AFF_GROUP);
|
||||
act("$N has disbanded the group.", TRUE, f->follower, NULL, ch, TO_CHAR);
|
||||
if (!AFF_FLAGGED(f->follower, AFF_CHARM))
|
||||
stop_follower(f->follower);
|
||||
}
|
||||
|
||||
leave_group(ch);
|
||||
} else if (is_abbrev(buf, "option")) {
|
||||
skip_spaces(&argument);
|
||||
if (!GROUP(ch)) {
|
||||
send_to_char(ch, "But you aren't part of a group!\r\n");
|
||||
return;
|
||||
} else if (GROUP_LEADER(GROUP(ch)) != ch) {
|
||||
send_to_char(ch, "Only the group leader can adjust the group flags.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
REMOVE_BIT_AR(AFF_FLAGS(ch), AFF_GROUP);
|
||||
send_to_char(ch, "You disband the group.\r\n");
|
||||
return;
|
||||
}
|
||||
if (!(tch = get_char_vis(ch, buf, NULL, FIND_CHAR_ROOM))) {
|
||||
send_to_char(ch, "There is no such person!\r\n");
|
||||
return;
|
||||
}
|
||||
if (tch->master != ch) {
|
||||
send_to_char(ch, "That person is not following you!\r\n");
|
||||
return;
|
||||
if (is_abbrev(argument, "open")) {
|
||||
TOGGLE_BIT(GROUP_FLAGS(GROUP(ch)), GROUP_OPEN);
|
||||
send_to_char(ch, "The group is now %s to new members.\r\n", IS_SET(GROUP_FLAGS(GROUP(ch)), GROUP_OPEN) ? "open" : "closed");
|
||||
} else if (is_abbrev(argument, "anonymous")) {
|
||||
TOGGLE_BIT(GROUP_FLAGS(GROUP(ch)), GROUP_ANON);
|
||||
send_to_char(ch, "The group location is now %s to other players.\r\n", IS_SET(GROUP_FLAGS(GROUP(ch)), GROUP_ANON) ? "invisible" : "visible");
|
||||
} else
|
||||
send_to_char(ch, "The flag options are: Open, Anonymous\r\n");
|
||||
} else {
|
||||
send_to_char(ch, "You must specify a group option, or type HELP GROUP for more info.\r\n");
|
||||
}
|
||||
|
||||
if (!AFF_FLAGGED(tch, AFF_GROUP)) {
|
||||
send_to_char(ch, "That person isn't in your group.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
REMOVE_BIT_AR(AFF_FLAGS(tch), AFF_GROUP);
|
||||
|
||||
act("$N is no longer a member of your group.", FALSE, ch, 0, tch, TO_CHAR);
|
||||
act("You have been kicked out of $n's group!", FALSE, ch, 0, tch, TO_VICT);
|
||||
act("$N has been kicked out of $n's group!", FALSE, ch, 0, tch, TO_NOTVICT);
|
||||
|
||||
if (!AFF_FLAGGED(tch, AFF_CHARM))
|
||||
stop_follower(tch);
|
||||
}
|
||||
|
||||
ACMD(do_report)
|
||||
{
|
||||
char buf[MAX_STRING_LENGTH];
|
||||
struct char_data *k;
|
||||
struct follow_type *f;
|
||||
struct group_data *group;
|
||||
|
||||
if (!AFF_FLAGGED(ch, AFF_GROUP)) {
|
||||
if ((group = GROUP(ch)) == NULL) {
|
||||
send_to_char(ch, "But you are not a member of any group!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "$n reports: %d/%dH, %d/%dM, %d/%dV\r\n",
|
||||
send_to_group(NULL, group, "%s reports: %d/%dH, %d/%dM, %d/%dV\r\n",
|
||||
GET_NAME(ch),
|
||||
GET_HIT(ch), GET_MAX_HIT(ch),
|
||||
GET_MANA(ch), GET_MAX_MANA(ch),
|
||||
GET_MOVE(ch), GET_MAX_MOVE(ch));
|
||||
|
||||
k = (ch->master ? ch->master : ch);
|
||||
|
||||
for (f = k->followers; f; f = f->next)
|
||||
if (AFF_FLAGGED(f->follower, AFF_GROUP) && f->follower != ch)
|
||||
act(buf, TRUE, ch, NULL, f->follower, TO_VICT);
|
||||
|
||||
if (k != ch)
|
||||
act(buf, TRUE, ch, NULL, k, TO_VICT);
|
||||
|
||||
send_to_char(ch, "You report to the group.\r\n");
|
||||
}
|
||||
|
||||
ACMD(do_split)
|
||||
{
|
||||
char buf[MAX_INPUT_LENGTH];
|
||||
int amount, num, share, rest;
|
||||
int amount, num = 0, share, rest;
|
||||
size_t len;
|
||||
struct char_data *k;
|
||||
struct follow_type *f;
|
||||
|
||||
|
||||
if (IS_NPC(ch))
|
||||
return;
|
||||
|
||||
|
@ -513,20 +499,13 @@ ACMD(do_split)
|
|||
send_to_char(ch, "You don't seem to have that much gold to split.\r\n");
|
||||
return;
|
||||
}
|
||||
k = (ch->master ? ch->master : ch);
|
||||
|
||||
if (GROUP(ch))
|
||||
while ((k = (struct char_data *) simple_list(GROUP(ch)->members)) != NULL)
|
||||
if (IN_ROOM(ch) == IN_ROOM(k) && !IS_NPC(k))
|
||||
num++;
|
||||
|
||||
if (AFF_FLAGGED(k, AFF_GROUP) && (IN_ROOM(k) == IN_ROOM(ch)))
|
||||
num = 1;
|
||||
else
|
||||
num = 0;
|
||||
|
||||
for (f = k->followers; f; f = f->next)
|
||||
if (AFF_FLAGGED(f->follower, AFF_GROUP) &&
|
||||
(!IS_NPC(f->follower)) &&
|
||||
(IN_ROOM(f->follower) == IN_ROOM(ch)))
|
||||
num++;
|
||||
|
||||
if (num && AFF_FLAGGED(ch, AFF_GROUP)) {
|
||||
if (num && GROUP(ch)) {
|
||||
share = amount / num;
|
||||
rest = amount % num;
|
||||
} else {
|
||||
|
@ -544,22 +523,13 @@ ACMD(do_split)
|
|||
"%d coin%s %s not splitable, so %s keeps the money.\r\n", rest,
|
||||
(rest == 1) ? "" : "s", (rest == 1) ? "was" : "were", GET_NAME(ch));
|
||||
}
|
||||
if (AFF_FLAGGED(k, AFF_GROUP) && IN_ROOM(k) == IN_ROOM(ch) &&
|
||||
!IS_NPC(k) && k != ch) {
|
||||
increase_gold(k, share);
|
||||
send_to_char(k, "%s", buf);
|
||||
}
|
||||
|
||||
for (f = k->followers; f; f = f->next) {
|
||||
if (AFF_FLAGGED(f->follower, AFF_GROUP) &&
|
||||
(!IS_NPC(f->follower)) &&
|
||||
(IN_ROOM(f->follower) == IN_ROOM(ch)) &&
|
||||
f->follower != ch) {
|
||||
while ((k = (struct char_data *) simple_list(GROUP(ch)->members)) != NULL)
|
||||
if (k != ch && IN_ROOM(ch) == IN_ROOM(k) && !IS_NPC(k)) {
|
||||
increase_gold(k, share);
|
||||
send_to_char(k, "%s", buf);
|
||||
}
|
||||
|
||||
increase_gold(f->follower, share);
|
||||
send_to_char(f->follower, "%s", buf);
|
||||
}
|
||||
}
|
||||
send_to_char(ch, "You split %d coins among %d members -- %d coins each.\r\n",
|
||||
amount, num, share);
|
||||
|
||||
|
|
|
@ -1245,6 +1245,27 @@ void do_cheat(struct char_data *ch)
|
|||
save_char(ch);
|
||||
}
|
||||
|
||||
void return_to_char(struct char_data * ch)
|
||||
{
|
||||
/* If someone switched into your original body, disconnect them. - JE
|
||||
* Zmey: here we put someone switched in our body to disconnect state but
|
||||
* we must also NULL his pointer to our character, otherwise close_socket()
|
||||
* will damage our character's pointer to our descriptor (which is assigned
|
||||
* below in this function). */
|
||||
if (ch->desc->original->desc) {
|
||||
ch->desc->original->desc->character = NULL;
|
||||
STATE(ch->desc->original->desc) = CON_DISCONNECT;
|
||||
}
|
||||
|
||||
/* Now our descriptor points to our original body. */
|
||||
ch->desc->character = ch->desc->original;
|
||||
ch->desc->original = NULL;
|
||||
|
||||
/* And our body's pointer to descriptor now points to our descriptor. */
|
||||
ch->desc->character->desc = ch->desc;
|
||||
ch->desc = NULL;
|
||||
}
|
||||
|
||||
ACMD(do_return)
|
||||
{
|
||||
if (!IS_NPC(ch) && !ch->desc->original) {
|
||||
|
@ -1258,24 +1279,7 @@ ACMD(do_return)
|
|||
|
||||
if (ch->desc && ch->desc->original) {
|
||||
send_to_char(ch, "You return to your original body.\r\n");
|
||||
|
||||
/* If someone switched into your original body, disconnect them. - JE
|
||||
* Zmey: here we put someone switched in our body to disconnect state but
|
||||
* we must also NULL his pointer to our character, otherwise close_socket()
|
||||
* will damage our character's pointer to our descriptor (which is assigned
|
||||
* below in this function). */
|
||||
if (ch->desc->original->desc) {
|
||||
ch->desc->original->desc->character = NULL;
|
||||
STATE(ch->desc->original->desc) = CON_DISCONNECT;
|
||||
}
|
||||
|
||||
/* Now our descriptor points to our original body. */
|
||||
ch->desc->character = ch->desc->original;
|
||||
ch->desc->original = NULL;
|
||||
|
||||
/* And our body's pointer to descriptor now points to our descriptor. */
|
||||
ch->desc->character->desc = ch->desc;
|
||||
ch->desc = NULL;
|
||||
return_to_char(ch);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2169,7 +2173,6 @@ ACMD(do_wiznet)
|
|||
int level = LVL_IMMORT;
|
||||
|
||||
skip_spaces(&argument);
|
||||
delete_doubledollar(argument);
|
||||
|
||||
if (!*argument) {
|
||||
send_to_char(ch, "Usage: wiznet [ #<level> ] [<text> | *<emotetext> | @ ]\r\n");
|
||||
|
@ -3637,10 +3640,9 @@ ACMD (do_zcheck)
|
|||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"- Has %d experience (limit: %d)\r\n",
|
||||
GET_EXP(mob), MAX_EXP_ALLOWED);
|
||||
if ((AFF_FLAGGED(mob, AFF_GROUP) || AFF_FLAGGED(mob, AFF_CHARM) || AFF_FLAGGED(mob, AFF_POISON)) && (found = 1))
|
||||
if ((AFF_FLAGGED(mob, AFF_CHARM) || AFF_FLAGGED(mob, AFF_POISON)) && (found = 1))
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"- Has illegal affection bits set (%s %s %s)\r\n",
|
||||
AFF_FLAGGED(mob, AFF_GROUP) ? "GROUP" : "",
|
||||
"- Has illegal affection bits set (%s %s)\r\n",
|
||||
AFF_FLAGGED(mob, AFF_CHARM) ? "CHARM" : "",
|
||||
AFF_FLAGGED(mob, AFF_POISON) ? "POISON" : "");
|
||||
|
||||
|
@ -4153,6 +4155,11 @@ ACMD(do_copyover)
|
|||
/* For each playing descriptor, save its state */
|
||||
for (d = descriptor_list; d ; d = d_next) {
|
||||
struct char_data * och = d->character;
|
||||
|
||||
/* If d is currently in someone else's body, return them. */
|
||||
if (och && d->original)
|
||||
return_to_char(och);
|
||||
|
||||
/* We delete from the list , so need to save this */
|
||||
d_next = d->next;
|
||||
|
||||
|
|
|
@ -1609,6 +1609,7 @@ void init_spell_levels(void)
|
|||
spell_level(SPELL_REMOVE_POISON, CLASS_CLERIC, 10);
|
||||
spell_level(SPELL_IDENTIFY, CLASS_CLERIC, 11);
|
||||
spell_level(SPELL_WORD_OF_RECALL, CLASS_CLERIC, 12);
|
||||
spell_level(SPELL_DARKNESS, CLASS_CLERIC, 12);
|
||||
spell_level(SPELL_EARTHQUAKE, CLASS_CLERIC, 12);
|
||||
spell_level(SPELL_DISPEL_EVIL, CLASS_CLERIC, 14);
|
||||
spell_level(SPELL_DISPEL_GOOD, CLASS_CLERIC, 14);
|
||||
|
|
23
src/comm.c
23
src/comm.c
|
@ -2418,6 +2418,29 @@ void send_to_room(room_rnum room, const char *messg, ...)
|
|||
}
|
||||
}
|
||||
|
||||
/* Sends a message to the entire group, except for ch.
|
||||
* Send 'ch' as NULL, if you want to message to reach
|
||||
* everyone. -Vatiken */
|
||||
void send_to_group(struct char_data *ch, struct group_data *group, const char * msg, ...)
|
||||
{
|
||||
struct char_data *tch;
|
||||
va_list args;
|
||||
|
||||
if (msg == NULL)
|
||||
return;
|
||||
|
||||
while ((tch = simple_list(group->members)) != NULL) {
|
||||
if (tch != ch && !IS_NPC(tch) && tch->desc && STATE(tch->desc) == CON_PLAYING) {
|
||||
write_to_output(tch->desc, "%s[%sGroup%s]%s ",
|
||||
CCGRN(tch, C_NRM), CBGRN(tch, C_NRM), CCGRN(tch, C_NRM), CCNRM(tch, C_NRM));
|
||||
va_start(args, msg);
|
||||
vwrite_to_output(tch->desc, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Thx to Jamie Nelson of 4D for this contribution */
|
||||
void send_to_range(room_vnum start, room_vnum finish, const char *messg, ...)
|
||||
{
|
||||
|
|
|
@ -27,6 +27,8 @@ void send_to_room(room_rnum room, const char *messg, ...) __attribute__ ((format
|
|||
(printf, 2, 3)));
|
||||
void send_to_outdoor(const char *messg, ...) __attribute__ ((format (printf, 1,
|
||||
2)));
|
||||
void send_to_group(struct char_data *ch, struct group_data *group, const char * msg, ...) __attribute__ ((format
|
||||
(printf, 3, 4)));
|
||||
void send_to_range(room_vnum start, room_vnum finish, const char *messg, ...)
|
||||
__attribute__ ((format (printf, 3, 4)));
|
||||
|
||||
|
|
15
src/db.c
15
src/db.c
|
@ -511,6 +511,16 @@ void destroy_db(void)
|
|||
free(world[cnt].description);
|
||||
free_extra_descriptions(world[cnt].ex_description);
|
||||
|
||||
if (world[cnt].events != NULL) {
|
||||
if (world[cnt].events->iSize > 0) {
|
||||
struct event * pEvent;
|
||||
|
||||
while ((pEvent = simple_list(world[cnt].events)) != NULL)
|
||||
event_cancel(pEvent);
|
||||
}
|
||||
free_list(world[cnt].events);
|
||||
}
|
||||
|
||||
/* free any assigned scripts */
|
||||
if (SCRIPT(&world[cnt]))
|
||||
extract_script(&world[cnt], WLD_TRIGGER);
|
||||
|
@ -651,6 +661,7 @@ void boot_db(void)
|
|||
|
||||
log("Initialize Global Lists");
|
||||
global_lists = create_list();
|
||||
group_list = create_list();
|
||||
|
||||
log("Initializing Events");
|
||||
init_events();
|
||||
|
@ -1724,7 +1735,6 @@ void parse_mobile(FILE *mob_f, int nr)
|
|||
/* Make some basic checks. */
|
||||
REMOVE_BIT_AR(AFF_FLAGS(mob_proto + i), AFF_CHARM);
|
||||
REMOVE_BIT_AR(AFF_FLAGS(mob_proto + i), AFF_POISON);
|
||||
REMOVE_BIT_AR(AFF_FLAGS(mob_proto + i), AFF_GROUP);
|
||||
REMOVE_BIT_AR(AFF_FLAGS(mob_proto + i), AFF_SLEEP);
|
||||
if (MOB_FLAGGED(mob_proto + i, MOB_AGGRESSIVE) && MOB_FLAGGED(mob_proto + i, MOB_AGGR_GOOD))
|
||||
REMOVE_BIT_AR(MOB_FLAGS(mob_proto + i), MOB_AGGR_GOOD);
|
||||
|
@ -2346,7 +2356,8 @@ struct char_data *create_char(void)
|
|||
|
||||
void new_mobile_data(struct char_data *ch)
|
||||
{
|
||||
ch->events = create_list();
|
||||
ch->events = NULL;
|
||||
ch->group = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -872,18 +872,18 @@ ACMD(do_mtransform)
|
|||
int keep_hp = 1; /* new mob keeps the old mob's hp/max hp/exp */
|
||||
int pos;
|
||||
|
||||
if (!MOB_OR_IMPL(ch)) {
|
||||
send_to_char(ch, "Huh?!?\r\n");
|
||||
return;
|
||||
}
|
||||
if (!MOB_OR_IMPL(ch)) {
|
||||
send_to_char(ch, "Huh?!?\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (AFF_FLAGGED(ch, AFF_CHARM))
|
||||
return;
|
||||
if (AFF_FLAGGED(ch, AFF_CHARM))
|
||||
return;
|
||||
|
||||
if (ch->desc) {
|
||||
send_to_char(ch, "You've got no VNUM to return to, dummy! try 'switch'\r\n");
|
||||
return;
|
||||
}
|
||||
if (ch->desc) {
|
||||
send_to_char(ch, "You've got no VNUM to return to, dummy! try 'switch'\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
one_argument(argument, arg);
|
||||
|
||||
|
@ -935,11 +935,13 @@ ACMD(do_mtransform)
|
|||
tmpmob.proto_script = ch->proto_script;
|
||||
tmpmob.script = ch->script;
|
||||
tmpmob.memory = ch->memory;
|
||||
tmpmob.events = ch->events;
|
||||
tmpmob.next_in_room = ch->next_in_room;
|
||||
tmpmob.next = ch->next;
|
||||
tmpmob.next_fighting = ch->next_fighting;
|
||||
tmpmob.followers = ch->followers;
|
||||
tmpmob.master = ch->master;
|
||||
tmpmob.group = ch->group;
|
||||
|
||||
GET_WAS_IN(&tmpmob) = GET_WAS_IN(ch);
|
||||
if (keep_hp) {
|
||||
|
|
65
src/fight.c
65
src/fight.c
|
@ -271,6 +271,10 @@ void raw_kill(struct char_data * ch, struct char_data * killer)
|
|||
if (killer)
|
||||
autoquest_trigger_check(killer, ch, NULL, AQ_MOB_KILL);
|
||||
|
||||
/* Alert Group if Applicable */
|
||||
if (GROUP(ch))
|
||||
send_to_group(ch, GROUP(ch), "%s has died.\r\n", GET_NAME(ch));
|
||||
|
||||
update_pos(ch);
|
||||
|
||||
make_corpse(ch);
|
||||
|
@ -316,20 +320,11 @@ static void perform_group_gain(struct char_data *ch, int base,
|
|||
|
||||
static void group_gain(struct char_data *ch, struct char_data *victim)
|
||||
{
|
||||
int tot_members, base, tot_gain;
|
||||
int tot_members = 0, base, tot_gain;
|
||||
struct char_data *k;
|
||||
struct follow_type *f;
|
||||
|
||||
if (!(k = ch->master))
|
||||
k = ch;
|
||||
|
||||
if (AFF_FLAGGED(k, AFF_GROUP) && (IN_ROOM(k) == IN_ROOM(ch)))
|
||||
tot_members = 1;
|
||||
else
|
||||
tot_members = 0;
|
||||
|
||||
for (f = k->followers; f; f = f->next)
|
||||
if (AFF_FLAGGED(f->follower, AFF_GROUP) && IN_ROOM(f->follower) == IN_ROOM(ch))
|
||||
|
||||
while ((k = (struct char_data *) simple_list(GROUP(ch)->members)) != NULL)
|
||||
if (IN_ROOM(ch) == IN_ROOM(k))
|
||||
tot_members++;
|
||||
|
||||
/* round up to the nearest tot_members */
|
||||
|
@ -344,12 +339,9 @@ static void group_gain(struct char_data *ch, struct char_data *victim)
|
|||
else
|
||||
base = 0;
|
||||
|
||||
if (AFF_FLAGGED(k, AFF_GROUP) && IN_ROOM(k) == IN_ROOM(ch))
|
||||
perform_group_gain(k, base, victim);
|
||||
|
||||
for (f = k->followers; f; f = f->next)
|
||||
if (AFF_FLAGGED(f->follower, AFF_GROUP) && IN_ROOM(f->follower) == IN_ROOM(ch))
|
||||
perform_group_gain(f->follower, base, victim);
|
||||
while ((k = (struct char_data *) simple_list(GROUP(ch)->members)) != NULL)
|
||||
if (IN_ROOM(k) == IN_ROOM(ch))
|
||||
perform_group_gain(k, base, victim);
|
||||
}
|
||||
|
||||
static void solo_gain(struct char_data *ch, struct char_data *victim)
|
||||
|
@ -738,7 +730,7 @@ int damage(struct char_data *ch, struct char_data *victim, int dam, int attackty
|
|||
/* Uh oh. Victim died. */
|
||||
if (GET_POS(victim) == POS_DEAD) {
|
||||
if (ch != victim && (IS_NPC(victim) || victim->desc)) {
|
||||
if (AFF_FLAGGED(ch, AFF_GROUP))
|
||||
if (GROUP(ch))
|
||||
group_gain(ch, victim);
|
||||
else
|
||||
solo_gain(ch, victim);
|
||||
|
@ -762,7 +754,7 @@ int damage(struct char_data *ch, struct char_data *victim, int dam, int attackty
|
|||
}
|
||||
|
||||
die(victim, ch);
|
||||
if (IS_AFFECTED(ch, AFF_GROUP) && (local_gold > 0) && PRF_FLAGGED(ch, PRF_AUTOSPLIT) ) {
|
||||
if (GROUP(ch) && (local_gold > 0) && PRF_FLAGGED(ch, PRF_AUTOSPLIT) ) {
|
||||
generic_find("corpse", FIND_OBJ_ROOM, ch, &tmp_char, &corpse_obj);
|
||||
if (corpse_obj) {
|
||||
do_get(ch, "all.coin corpse", 0, 0);
|
||||
|
@ -905,8 +897,7 @@ void hit(struct char_data *ch, struct char_data *victim, int type)
|
|||
/* control the fights going on. Called every 2 seconds from comm.c. */
|
||||
void perform_violence(void)
|
||||
{
|
||||
struct char_data *ch;
|
||||
struct follow_type *k;
|
||||
struct char_data *ch, *tch;
|
||||
|
||||
for (ch = combat_list; ch; ch = next_combat_list) {
|
||||
next_combat_list = ch->next_fighting;
|
||||
|
@ -933,19 +924,25 @@ void perform_violence(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
for (k = ch->followers; k; k=k->next) {
|
||||
/* should followers auto-assist master? */
|
||||
if (!IS_NPC(k->follower) && !FIGHTING(k->follower) && PRF_FLAGGED(k->follower,
|
||||
PRF_AUTOASSIST) && (IN_ROOM(k->follower) == IN_ROOM(ch)))
|
||||
do_assist(k->follower, GET_NAME(ch), 0, 0);
|
||||
if (GROUP(ch)) {
|
||||
while ((tch = (struct char_data *) simple_list(GROUP(ch)->members)) != NULL) {
|
||||
if (tch == ch)
|
||||
continue;
|
||||
if (!IS_NPC(tch) && !PRF_FLAGGED(tch, PRF_AUTOASSIST))
|
||||
continue;
|
||||
if (IN_ROOM(ch) != IN_ROOM(tch))
|
||||
continue;
|
||||
if (FIGHTING(tch))
|
||||
continue;
|
||||
if (GET_POS(tch) != POS_STANDING)
|
||||
continue;
|
||||
if (!CAN_SEE(tch, ch))
|
||||
continue;
|
||||
|
||||
do_assist(tch, GET_NAME(ch), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* should master auto-assist followers? */
|
||||
if (ch->master && PRF_FLAGGED(ch->master, PRF_AUTOASSIST) &&
|
||||
FIGHTING(ch) && !FIGHTING(ch->master) && !IS_NPC(ch) &&
|
||||
(IN_ROOM(ch->master) == IN_ROOM(ch)) && !IS_NPC(ch->master))
|
||||
do_assist(ch->master, GET_NAME(ch), 0, 0);
|
||||
|
||||
hit(ch, FIGHTING(ch), TYPE_UNDEFINED);
|
||||
if (MOB_FLAGGED(ch, MOB_SPEC) && GET_MOB_SPEC(ch) && !MOB_FLAGGED(ch, MOB_NOTDEADYET)) {
|
||||
char actbuf[MAX_INPUT_LENGTH] = "";
|
||||
|
|
13
src/genwld.c
13
src/genwld.c
|
@ -17,6 +17,7 @@
|
|||
#include "genzon.h"
|
||||
#include "shop.h"
|
||||
#include "dg_olc.h"
|
||||
#include "mud_event.h"
|
||||
|
||||
|
||||
/* This function will copy the strings so be sure you free your own copies of
|
||||
|
@ -167,6 +168,16 @@ int delete_room(room_rnum rnum)
|
|||
extract_script(room, WLD_TRIGGER);
|
||||
free_proto_script(room, WLD_TRIGGER);
|
||||
|
||||
if (room->events != NULL) {
|
||||
if (room->events->iSize > 0) {
|
||||
struct event * pEvent;
|
||||
|
||||
while ((pEvent = simple_list(room->events)) != NULL)
|
||||
event_cancel(pEvent);
|
||||
}
|
||||
free_list(room->events);
|
||||
}
|
||||
|
||||
/* Change any exit going to this room to go the void. Also fix all the exits
|
||||
* pointing to rooms above this. */
|
||||
i = top_of_world + 1;
|
||||
|
@ -378,10 +389,12 @@ int copy_room(struct room_data *to, struct room_data *from)
|
|||
free_room_strings(to);
|
||||
*to = *from;
|
||||
copy_room_strings(to, from);
|
||||
to->events = from->events;
|
||||
|
||||
/* Don't put people and objects in two locations. Should this be done here? */
|
||||
from->people = NULL;
|
||||
from->contents = NULL;
|
||||
from->events = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,12 @@ zone_rnum create_new_zone(zone_vnum vzone_num, room_vnum bottom, room_vnum top,
|
|||
} else if (bottom > top) {
|
||||
*error = "Bottom room cannot be greater than top room.\r\n";
|
||||
return NOWHERE;
|
||||
} else if (bottom < 0) {
|
||||
*error = "Bottom room cannot be less then 0.\r\n";
|
||||
return NOWHERE;
|
||||
} else if (top >= IDXTYPE_MAX) {
|
||||
*error = "Top greater than IDXTYPE_MAX. (Commonly 65535)\r\n";
|
||||
return NOWHERE;
|
||||
}
|
||||
|
||||
for (i = 0; i < top_of_zone_table; i++)
|
||||
|
|
103
src/handler.c
103
src/handler.c
|
@ -15,6 +15,7 @@
|
|||
#include "comm.h"
|
||||
#include "db.h"
|
||||
#include "handler.h"
|
||||
#include "screen.h"
|
||||
#include "interpreter.h"
|
||||
#include "spells.h"
|
||||
#include "dg_scripts.h"
|
||||
|
@ -22,6 +23,7 @@
|
|||
#include "class.h"
|
||||
#include "fight.h"
|
||||
#include "quest.h"
|
||||
#include "mud_event.h"
|
||||
|
||||
/* local file scope variables */
|
||||
static int extractions_pending = 0;
|
||||
|
@ -910,6 +912,10 @@ void extract_char_final(struct char_data *ch)
|
|||
if (ch->followers || ch->master)
|
||||
die_follower(ch);
|
||||
|
||||
/* Check to see if we are grouped! */
|
||||
if (GROUP(ch))
|
||||
leave_group(ch);
|
||||
|
||||
/* transfer objects to room, if any */
|
||||
while (ch->carrying) {
|
||||
obj = ch->carrying;
|
||||
|
@ -1386,3 +1392,100 @@ int find_all_dots(char *arg)
|
|||
} else
|
||||
return (FIND_INDIV);
|
||||
}
|
||||
|
||||
/* Group Handlers */
|
||||
struct group_data * create_group(struct char_data * leader)
|
||||
{
|
||||
struct group_data * new_group;
|
||||
|
||||
/* Allocate Group Memory & Attach to Group List*/
|
||||
CREATE(new_group, struct group_data, 1);
|
||||
add_to_list(new_group, group_list);
|
||||
|
||||
/* Allocate Members List */
|
||||
new_group->members = create_list();
|
||||
|
||||
/* Clear Data */
|
||||
new_group->group_flags = 0;
|
||||
|
||||
/* Assign Data */
|
||||
SET_BIT(GROUP_FLAGS(new_group), GROUP_OPEN);
|
||||
|
||||
if (IS_NPC(leader))
|
||||
SET_BIT(GROUP_FLAGS(new_group), GROUP_NPC);
|
||||
|
||||
join_group(leader, new_group);
|
||||
|
||||
return (new_group);
|
||||
}
|
||||
|
||||
void free_group(struct group_data * group)
|
||||
{
|
||||
struct char_data *tch;
|
||||
struct iterator_data Iterator;
|
||||
|
||||
if (group->members->iSize) {
|
||||
for (tch = (struct char_data *) merge_iterator(&Iterator, group->members);
|
||||
tch;
|
||||
tch = next_in_list(&Iterator))
|
||||
leave_group(tch);
|
||||
|
||||
remove_iterator(&Iterator);
|
||||
}
|
||||
|
||||
free_list(group->members);
|
||||
remove_from_list(group, group_list);
|
||||
free(group);
|
||||
}
|
||||
|
||||
void leave_group(struct char_data *ch)
|
||||
{
|
||||
struct group_data *group;
|
||||
struct char_data *tch;
|
||||
struct iterator_data Iterator;
|
||||
bool found_pc = FALSE;
|
||||
|
||||
if ((group = ch->group) == NULL)
|
||||
return;
|
||||
|
||||
send_to_group(NULL, group, "%s has left the group.\r\n", GET_NAME(ch));
|
||||
|
||||
remove_from_list(ch, group->members);
|
||||
ch->group = NULL;
|
||||
|
||||
if (group->members->iSize) {
|
||||
for (tch = (struct char_data *) merge_iterator(&Iterator, group->members);
|
||||
tch; tch = next_in_list(&Iterator))
|
||||
if (!IS_NPC(tch))
|
||||
found_pc = TRUE;
|
||||
|
||||
remove_iterator(&Iterator);
|
||||
}
|
||||
|
||||
if (!found_pc)
|
||||
SET_BIT(GROUP_FLAGS(group), GROUP_NPC);
|
||||
|
||||
if (GROUP_LEADER(group) == ch && group->members->iSize) {
|
||||
group->leader = (struct char_data *) random_from_list(group->members);
|
||||
send_to_group(NULL, group, "%s has assumed leadership of the group.\r\n", GET_NAME(GROUP_LEADER(group)));
|
||||
} else if (group->members->iSize == 0)
|
||||
free_group(group);
|
||||
}
|
||||
|
||||
void join_group(struct char_data *ch, struct group_data *group)
|
||||
{
|
||||
add_to_list(ch, group->members);
|
||||
|
||||
if (group->leader == NULL)
|
||||
group->leader = ch;
|
||||
|
||||
ch->group = group;
|
||||
|
||||
if (IS_SET(group->group_flags, GROUP_NPC) && !IS_NPC(ch))
|
||||
REMOVE_BIT(GROUP_FLAGS(group), GROUP_NPC);
|
||||
|
||||
if (group->leader == ch)
|
||||
send_to_group(NULL, group, "%s becomes leader of the group.\r\n", GET_NAME(ch));
|
||||
else
|
||||
send_to_group(NULL, group, "%s joins the group.\r\n", GET_NAME(ch));
|
||||
}
|
||||
|
|
|
@ -77,6 +77,11 @@ int find_all_dots(char *arg);
|
|||
#define FIND_ALL 1
|
||||
#define FIND_ALLDOT 2
|
||||
|
||||
/* group */
|
||||
struct group_data * create_group(struct char_data * leader);
|
||||
void free_group(struct group_data * group);
|
||||
void leave_group(struct char_data *ch);
|
||||
void join_group(struct char_data *ch, struct group_data *group);
|
||||
|
||||
/* Generic Find */
|
||||
int generic_find(char *arg, bitvector_t bitvector, struct char_data *ch,
|
||||
|
|
|
@ -323,7 +323,6 @@ cpp_extern const struct command_info cmd_info[] = {
|
|||
{ "tstat" , "tstat" , POS_DEAD , do_tstat , LVL_BUILDER, 0 },
|
||||
|
||||
{ "unlock" , "unlock" , POS_SITTING , do_gen_door , 0, SCMD_UNLOCK },
|
||||
{ "ungroup" , "ungroup" , POS_DEAD , do_ungroup , 0, 0 },
|
||||
{ "unban" , "unban" , POS_DEAD , do_unban , LVL_GRGOD, 0 },
|
||||
{ "unaffect" , "unaffect", POS_DEAD , do_wizutil , LVL_GOD, SCMD_UNAFFECT },
|
||||
{ "uptime" , "uptime" , POS_DEAD , do_date , LVL_GOD, SCMD_UPTIME },
|
||||
|
@ -1140,7 +1139,6 @@ static int perform_dupe_check(struct descriptor_data *d)
|
|||
d->character->char_specials.timer = 0;
|
||||
REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_MAILING);
|
||||
REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_WRITING);
|
||||
REMOVE_BIT_AR(AFF_FLAGS(d->character), AFF_GROUP);
|
||||
STATE(d) = CON_PLAYING;
|
||||
MXPSendTag( d, "<VERSION>" );
|
||||
|
||||
|
@ -1416,7 +1414,6 @@ void nanny(struct descriptor_data *d, char *arg)
|
|||
REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_WRITING);
|
||||
REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_MAILING);
|
||||
REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_CRYO);
|
||||
REMOVE_BIT_AR(AFF_FLAGS(d->character), AFF_GROUP);
|
||||
d->character->player.time.logon = time(0);
|
||||
write_to_output(d, "Password: ");
|
||||
echo_off(d);
|
||||
|
|
19
src/lists.c
19
src/lists.c
|
@ -12,8 +12,13 @@
|
|||
#include "db.h"
|
||||
#include "dg_event.h"
|
||||
|
||||
static struct iterator_data Iterator;
|
||||
static bool loop = FALSE;
|
||||
static struct list_data *pLastList = NULL;
|
||||
|
||||
/* Global lists */
|
||||
struct list_data * global_lists = NULL;
|
||||
struct list_data * group_list = NULL;
|
||||
|
||||
struct list_data * create_list(void)
|
||||
{
|
||||
|
@ -53,7 +58,7 @@ void free_list(struct list_data * pList)
|
|||
{
|
||||
void * pContent;
|
||||
|
||||
simple_list(NULL);
|
||||
clear_simple_list();
|
||||
|
||||
if (pList->iSize)
|
||||
while ((pContent = simple_list(pList)))
|
||||
|
@ -225,6 +230,12 @@ struct item_data * find_in_list(void * pContent, struct list_data * pList)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void clear_simple_list(void)
|
||||
{
|
||||
loop = FALSE;
|
||||
pLastList = NULL;
|
||||
}
|
||||
|
||||
/** This is the "For Dummies" function, as although it's not as flexible,
|
||||
* it is even easier applied for list searches then using your own iterators
|
||||
* and next_in_list()
|
||||
|
@ -239,15 +250,11 @@ struct item_data * find_in_list(void * pContent, struct list_data * pList)
|
|||
|
||||
void * simple_list(struct list_data * pList)
|
||||
{
|
||||
static struct iterator_data Iterator;
|
||||
static bool loop = FALSE;
|
||||
static struct list_data *pLastList = NULL;
|
||||
void * pContent;
|
||||
|
||||
/* Reset List */
|
||||
if (pList == NULL) {
|
||||
loop = FALSE;
|
||||
pLastList = NULL;
|
||||
clear_simple_list();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ struct iterator_data {
|
|||
|
||||
/* Externals */
|
||||
extern struct list_data * global_lists;
|
||||
extern struct list_data * group_list;
|
||||
|
||||
/* Locals */
|
||||
void add_to_list(void * pContent, struct list_data * pList);
|
||||
|
@ -46,4 +47,5 @@ void remove_from_list(void * pContent, struct list_data * pList);
|
|||
struct item_data * find_in_list(void * pContent, struct list_data * pList);
|
||||
void * simple_list(struct list_data * pList);
|
||||
void free_list(struct list_data * pList);
|
||||
void clear_simple_list(void);
|
||||
#endif
|
||||
|
|
69
src/magic.c
69
src/magic.c
|
@ -21,6 +21,7 @@
|
|||
#include "dg_scripts.h"
|
||||
#include "class.h"
|
||||
#include "fight.h"
|
||||
#include "mud_event.h"
|
||||
|
||||
|
||||
/* local file scope function prototypes */
|
||||
|
@ -574,35 +575,22 @@ static void perform_mag_groups(int level, struct char_data *ch,
|
|||
* Just add a new case to perform_mag_groups. */
|
||||
void mag_groups(int level, struct char_data *ch, int spellnum, int savetype)
|
||||
{
|
||||
struct char_data *tch, *k;
|
||||
struct follow_type *f, *f_next;
|
||||
struct char_data *tch;
|
||||
|
||||
if (ch == NULL)
|
||||
return;
|
||||
|
||||
if (!AFF_FLAGGED(ch, AFF_GROUP))
|
||||
if (!GROUP(ch))
|
||||
return;
|
||||
if (ch->master != NULL)
|
||||
k = ch->master;
|
||||
else
|
||||
k = ch;
|
||||
for (f = k->followers; f; f = f_next) {
|
||||
f_next = f->next;
|
||||
tch = f->follower;
|
||||
|
||||
while ((tch = (struct char_data *) simple_list(GROUP(ch)->members)) != NULL) {
|
||||
if (IN_ROOM(tch) != IN_ROOM(ch))
|
||||
continue;
|
||||
if (!AFF_FLAGGED(tch, AFF_GROUP))
|
||||
continue;
|
||||
if (ch == tch)
|
||||
continue;
|
||||
perform_mag_groups(level, ch, tch, spellnum, savetype);
|
||||
}
|
||||
|
||||
if ((k != ch) && AFF_FLAGGED(k, AFF_GROUP))
|
||||
perform_mag_groups(level, ch, k, spellnum, savetype);
|
||||
perform_mag_groups(level, ch, ch, spellnum, savetype);
|
||||
}
|
||||
|
||||
|
||||
/* Mass spells affect every creature in the room except the caster. No spells
|
||||
* of this class currently implemented. */
|
||||
void mag_masses(int level, struct char_data *ch, int spellnum, int savetype)
|
||||
|
@ -663,8 +651,7 @@ void mag_areas(int level, struct char_data *ch, int spellnum, int savetype)
|
|||
continue;
|
||||
if (!IS_NPC(ch) && IS_NPC(tch) && AFF_FLAGGED(tch, AFF_CHARM))
|
||||
continue;
|
||||
if (!IS_NPC(tch) && spell_info[spellnum].violent && AFF_FLAGGED(tch, AFF_GROUP) && AFF_FLAGGED(ch, AFF_GROUP) &&
|
||||
( ((ch->master == NULL) ? ch : ch->master) == ((tch->master == NULL) ? tch : tch->master) ) )
|
||||
if (!IS_NPC(tch) && spell_info[spellnum].violent && GROUP(tch) && GROUP(ch) && GROUP(ch) == GROUP(tch))
|
||||
continue;
|
||||
if ((spellnum == SPELL_EARTHQUAKE) && AFF_FLAGGED(tch, AFF_FLYING))
|
||||
continue;
|
||||
|
@ -784,6 +771,9 @@ void mag_summons(int level, struct char_data *ch, struct obj_data *obj,
|
|||
act(mag_summon_msgs[msg], FALSE, ch, 0, mob, TO_ROOM);
|
||||
load_mtrigger(mob);
|
||||
add_follower(mob, ch);
|
||||
|
||||
if (GROUP(ch) && GROUP_LEADER(GROUP(ch)) == ch)
|
||||
join_group(mob, GROUP(ch));
|
||||
}
|
||||
if (handle_corpse) {
|
||||
for (tobj = obj->contains; tobj; tobj = next_obj) {
|
||||
|
@ -976,3 +966,42 @@ void mag_creations(int level, struct char_data *ch, int spellnum)
|
|||
load_otrigger(tobj);
|
||||
}
|
||||
|
||||
void mag_rooms(int level, struct char_data *ch, int spellnum)
|
||||
{
|
||||
room_rnum rnum;
|
||||
int duration;
|
||||
bool failure = FALSE;
|
||||
event_id IdNum = -1;
|
||||
const char *msg = NULL;
|
||||
const char *room = NULL;
|
||||
|
||||
rnum = IN_ROOM(ch);
|
||||
|
||||
if (ROOM_FLAGGED(rnum, ROOM_NOMAGIC))
|
||||
failure = TRUE;
|
||||
|
||||
switch (spellnum) {
|
||||
case SPELL_DARKNESS:
|
||||
IdNum = eSPL_DARKNESS;
|
||||
if (ROOM_FLAGGED(rnum, ROOM_DARK))
|
||||
failure = TRUE;
|
||||
|
||||
duration = 5;
|
||||
SET_BIT_AR(ROOM_FLAGS(rnum), ROOM_DARK);
|
||||
|
||||
msg = "You cast a shroud of darkness upon the area.";
|
||||
room = "$n casts a shroud of darkness upon this area.";
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (failure || IdNum == -1) {
|
||||
send_to_char(ch, "You failed!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
send_to_char(ch, "%s\r\n", msg);
|
||||
act(room, FALSE, ch, 0, 0, TO_ROOM);
|
||||
|
||||
NEW_EVENT(eSPL_DARKNESS, &world[rnum], NULL, duration * PASSES_PER_SEC);
|
||||
}
|
||||
|
|
|
@ -901,7 +901,6 @@ void medit_parse(struct descriptor_data *d, char *arg)
|
|||
/* Remove unwanted bits right away. */
|
||||
REMOVE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), AFF_CHARM);
|
||||
REMOVE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), AFF_POISON);
|
||||
REMOVE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), AFF_GROUP);
|
||||
REMOVE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), AFF_SLEEP);
|
||||
medit_disp_aff_flags(d);
|
||||
return;
|
||||
|
|
|
@ -156,6 +156,8 @@ void mobile_activity(void)
|
|||
{
|
||||
if (ch == vict || !IS_NPC(vict) || !FIGHTING(vict))
|
||||
continue;
|
||||
if (GROUP(vict) && GROUP(vict) == GROUP(ch))
|
||||
continue;
|
||||
if (IS_NPC(FIGHTING(vict)) || ch == FIGHTING(vict))
|
||||
continue;
|
||||
|
||||
|
|
|
@ -23,7 +23,8 @@ struct list_data * world_events = NULL;
|
|||
struct mud_event_list mud_event_index[] = {
|
||||
{ "Null" , NULL , -1 }, /* eNULL */
|
||||
{ "Protocol" , get_protocols , EVENT_DESC }, /* ePROTOCOLS */
|
||||
{ "Whirlwind" , event_whirlwind, EVENT_CHAR } /* eWHIRLWIND */
|
||||
{ "Whirlwind" , event_whirlwind, EVENT_CHAR }, /* eWHIRLWIND */
|
||||
{ "Spell:Darkness",event_countdown, EVENT_ROOM } /* eSPL_DARKNESS */
|
||||
};
|
||||
|
||||
/* init_events() is the ideal function for starting global events. This
|
||||
|
@ -54,6 +55,8 @@ EVENTFUNC(event_countdown)
|
|||
{
|
||||
struct mud_event_data * pMudEvent;
|
||||
struct char_data * ch = NULL;
|
||||
struct room_data * room = NULL;
|
||||
room_rnum rnum = NOWHERE;
|
||||
|
||||
pMudEvent = (struct mud_event_data * ) event_obj;
|
||||
|
||||
|
@ -61,11 +64,19 @@ EVENTFUNC(event_countdown)
|
|||
case EVENT_CHAR:
|
||||
ch = (struct char_data * ) pMudEvent->pStruct;
|
||||
break;
|
||||
case EVENT_ROOM:
|
||||
room = (struct room_data * ) pMudEvent->pStruct;
|
||||
rnum = real_room(room->number);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (pMudEvent->iId) {
|
||||
case eSPL_DARKNESS:
|
||||
REMOVE_BIT_AR(ROOM_FLAGS(rnum), ROOM_DARK);
|
||||
send_to_room(rnum, "The dark shroud disappates.\r\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -82,6 +93,7 @@ void attach_mud_event(struct mud_event_data *pMudEvent, long time)
|
|||
struct event * pEvent;
|
||||
struct descriptor_data * d;
|
||||
struct char_data * ch;
|
||||
struct room_data * room;
|
||||
|
||||
pEvent = event_create(mud_event_index[pMudEvent->iId].func, pMudEvent, time);
|
||||
pEvent->isMudEvent = TRUE;
|
||||
|
@ -97,8 +109,20 @@ void attach_mud_event(struct mud_event_data *pMudEvent, long time)
|
|||
break;
|
||||
case EVENT_CHAR:
|
||||
ch = (struct char_data *) pMudEvent->pStruct;
|
||||
|
||||
if (ch->events == NULL)
|
||||
ch->events = create_list();
|
||||
|
||||
add_to_list(pEvent, ch->events);
|
||||
break;
|
||||
case EVENT_ROOM:
|
||||
room = (struct room_data *) pMudEvent->pStruct;
|
||||
|
||||
if (room->events == NULL)
|
||||
room->events = create_list();
|
||||
|
||||
add_to_list(pEvent, room->events);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,6 +146,7 @@ void free_mud_event(struct mud_event_data *pMudEvent)
|
|||
{
|
||||
struct descriptor_data * d;
|
||||
struct char_data * ch;
|
||||
struct room_data * room;
|
||||
|
||||
switch (mud_event_index[pMudEvent->iId].iEvent_Type) {
|
||||
case EVENT_WORLD:
|
||||
|
@ -134,6 +159,20 @@ void free_mud_event(struct mud_event_data *pMudEvent)
|
|||
case EVENT_CHAR:
|
||||
ch = (struct char_data *) pMudEvent->pStruct;
|
||||
remove_from_list(pMudEvent->pEvent, ch->events);
|
||||
|
||||
if (ch->events->iSize == 0) {
|
||||
free_list(ch->events);
|
||||
ch->events = NULL;
|
||||
}
|
||||
break;
|
||||
case EVENT_ROOM:
|
||||
room = (struct room_data *) pMudEvent->pStruct;
|
||||
remove_from_list(pMudEvent->pEvent, room->events);
|
||||
|
||||
if (room->events->iSize == 0) {
|
||||
free_list(room->events);
|
||||
room->events = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -150,10 +189,13 @@ struct mud_event_data * char_has_mud_event(struct char_data * ch, event_id iId)
|
|||
struct mud_event_data * pMudEvent;
|
||||
bool found = FALSE;
|
||||
|
||||
if (ch->events == NULL)
|
||||
return NULL;
|
||||
|
||||
if (ch->events->iSize == 0)
|
||||
return NULL;
|
||||
|
||||
simple_list(NULL);
|
||||
clear_simple_list();
|
||||
|
||||
while ((pEvent = (struct event *) simple_list(ch->events)) != NULL) {
|
||||
if (!pEvent->isMudEvent)
|
||||
|
@ -164,9 +206,7 @@ struct mud_event_data * char_has_mud_event(struct char_data * ch, event_id iId)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
simple_list(NULL);
|
||||
|
||||
|
||||
if (found)
|
||||
return (pMudEvent);
|
||||
|
||||
|
@ -183,11 +223,46 @@ void clear_char_event_list(struct char_data * ch)
|
|||
if (ch->events->iSize == 0)
|
||||
return;
|
||||
|
||||
simple_list(NULL);
|
||||
clear_simple_list();
|
||||
|
||||
while ((pEvent = (struct event *) simple_list(ch->events)) != NULL) {
|
||||
event_cancel(pEvent);
|
||||
}
|
||||
|
||||
simple_list(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* change_event_duration contributed by Ripley */
|
||||
void change_event_duration(struct char_data * ch, event_id iId, long time) {
|
||||
|
||||
struct event * pEvent;
|
||||
struct mud_event_data * pMudEvent;
|
||||
bool found = FALSE;
|
||||
|
||||
if (ch->events == NULL);
|
||||
return;
|
||||
|
||||
if (ch->events->iSize == 0)
|
||||
return;
|
||||
|
||||
clear_simple_list();
|
||||
|
||||
while ((pEvent = (struct event *) simple_list(ch->events)) != NULL) {
|
||||
|
||||
if (!pEvent->isMudEvent)
|
||||
continue;
|
||||
|
||||
pMudEvent = (struct mud_event_data * ) pEvent->event_obj;
|
||||
|
||||
if (pMudEvent->iId == iId) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
/* So we found the offending event, now build a new one, with the new time */
|
||||
attach_mud_event(new_mud_event(iId, pMudEvent->pStruct, pMudEvent->sVariables), time);
|
||||
event_cancel(pEvent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#define EVENT_WORLD 0
|
||||
#define EVENT_DESC 1
|
||||
#define EVENT_CHAR 2
|
||||
#define EVENT_ROOM 3
|
||||
|
||||
#define NEW_EVENT(event_id, struct, var, time) (attach_mud_event(new_mud_event(event_id, struct, var), time))
|
||||
|
||||
|
@ -25,6 +26,7 @@ typedef enum {
|
|||
eNULL,
|
||||
ePROTOCOLS, /* The Protocol Detection Event */
|
||||
eWHIRLWIND, /* The Whirlwind Attack */
|
||||
eSPL_DARKNESS, /* Darkness Spell */
|
||||
} event_id;
|
||||
|
||||
struct mud_event_list {
|
||||
|
|
|
@ -1026,11 +1026,15 @@ obj_save_data *objsave_parse_objects(FILE *fl)
|
|||
if (*line == '#') {
|
||||
/* check for false alarm. */
|
||||
if (sscanf(line, "#%d", &nr) == 1) {
|
||||
/* Do not save an object if it has been deleted */
|
||||
if (real_object(nr) == NOTHING) {
|
||||
log("SYSERR: Protection: deleting object %d.", nr);
|
||||
/* If we attempt to load an object with a legal VNUM 0-65534, that
|
||||
* does not exist, skip it. If the object has a VNUM of NOTHING or
|
||||
* 65535, then we assume it doesn't exist on purpose. (Custom Item,
|
||||
* Coins, Corpse, etc...) */
|
||||
if (real_object(nr) == NOTHING && nr != NOTHING) {
|
||||
log("SYSERR: Prevented loading of non-existant item #%d.", nr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (temp) {
|
||||
current->obj = temp;
|
||||
CREATE(current->next, obj_save_data, 1);
|
||||
|
@ -1060,12 +1064,11 @@ obj_save_data *objsave_parse_objects(FILE *fl)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Should never get here, but since we did in the past, I'll put
|
||||
* a safety check in. */
|
||||
if (temp == NULL) {
|
||||
log("SYSERR: Attempting to parse obj_save_data on NULL object.");
|
||||
abort();
|
||||
}
|
||||
/* If "temp" is NULL, we are most likely progressing through
|
||||
* a non-existant object, so just keep continuing till we find
|
||||
* the next object */
|
||||
if (temp == NULL)
|
||||
continue;
|
||||
|
||||
tag_argument(line, tag);
|
||||
num = atoi(line);
|
||||
|
|
|
@ -177,6 +177,9 @@ void redit_setup_existing(struct descriptor_data *d, int real_num)
|
|||
/* and you are your next_in_room -- anderyu (10-05-22) */
|
||||
room->people = NULL;
|
||||
|
||||
/* Nullify the events structure. */
|
||||
room->events = NULL;
|
||||
|
||||
/* Allocate space for all strings. */
|
||||
room->name = str_udup(world[real_num].name);
|
||||
room->description = str_udup(world[real_num].description);
|
||||
|
|
|
@ -263,6 +263,9 @@ int call_magic(struct char_data *caster, struct char_data *cvict,
|
|||
if (IS_SET(SINFO.routines, MAG_CREATIONS))
|
||||
mag_creations(level, caster, spellnum);
|
||||
|
||||
if (IS_SET(SINFO.routines, MAG_ROOMS))
|
||||
mag_rooms(level, caster, spellnum);
|
||||
|
||||
if (IS_SET(SINFO.routines, MAG_MANUAL))
|
||||
switch (spellnum) {
|
||||
case SPELL_CHARM: MANUAL_SPELL(spell_charm); break;
|
||||
|
@ -473,7 +476,7 @@ int cast_spell(struct char_data *ch, struct char_data *tch,
|
|||
send_to_char(ch, "You cannot cast this spell upon yourself!\r\n");
|
||||
return (0);
|
||||
}
|
||||
if (IS_SET(SINFO.routines, MAG_GROUPS) && !AFF_FLAGGED(ch, AFF_GROUP)) {
|
||||
if (IS_SET(SINFO.routines, MAG_GROUPS) && !GROUP(ch)) {
|
||||
send_to_char(ch, "You can't cast this spell if you're not in a group!\r\n");
|
||||
return (0);
|
||||
}
|
||||
|
@ -789,6 +792,10 @@ void mag_assign_spells(void)
|
|||
TAR_CHAR_ROOM | TAR_OBJ_INV, TRUE, MAG_AFFECTS | MAG_ALTER_OBJS,
|
||||
"You feel more optimistic.");
|
||||
|
||||
spello(SPELL_DARKNESS, "darkness", 30, 5, 4, POS_STANDING,
|
||||
TAR_IGNORE, FALSE, MAG_ROOMS,
|
||||
NULL);
|
||||
|
||||
spello(SPELL_DETECT_ALIGN, "detect alignment", 20, 10, 2, POS_STANDING,
|
||||
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
|
||||
"You feel less aware.");
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#define MAG_SUMMONS (1 << 8)
|
||||
#define MAG_CREATIONS (1 << 9)
|
||||
#define MAG_MANUAL (1 << 10)
|
||||
#define MAG_ROOMS (1 << 11)
|
||||
|
||||
#define TYPE_UNDEFINED (-1)
|
||||
#define SPELL_RESERVED_DBC 0 /* SKILL NUMBER ZERO -- RESERVED */
|
||||
|
@ -91,8 +92,9 @@
|
|||
#define SPELL_WATERWALK 51 /* Reserved Skill[] DO NOT CHANGE */
|
||||
#define SPELL_IDENTIFY 52 /* Reserved Skill[] DO NOT CHANGE */
|
||||
#define SPELL_FLY 53 /* Reserved Skill[] DO NOT CHANGE */
|
||||
#define SPELL_DARKNESS 54
|
||||
/** Total Number of defined spells */
|
||||
#define NUM_SPELLS 53
|
||||
#define NUM_SPELLS 54
|
||||
|
||||
/* Insert new spells here, up to MAX_SPELLS */
|
||||
#define MAX_SPELLS 130
|
||||
|
@ -241,6 +243,8 @@ void mag_masses(int level, struct char_data *ch, int spellnum, int savetype);
|
|||
|
||||
void mag_areas(int level, struct char_data *ch, int spellnum, int savetype);
|
||||
|
||||
void mag_rooms(int level, struct char_data *ch, int spellnum);
|
||||
|
||||
void mag_summons(int level, struct char_data *ch, struct obj_data *obj,
|
||||
int spellnum, int savetype);
|
||||
|
||||
|
|
|
@ -148,6 +148,11 @@
|
|||
|
||||
#define HISTORY_SIZE 5 /**< Number of last commands kept in each history */
|
||||
|
||||
/* Group Defines */
|
||||
#define GROUP_OPEN (1 << 0) /**< Group is open for members */
|
||||
#define GROUP_ANON (1 << 1) /**< Group is Anonymous */
|
||||
#define GROUP_NPC (1 << 2) /**< Group created by NPC and thus not listed */
|
||||
|
||||
/* PC classes */
|
||||
#define CLASS_UNDEFINED (-1) /**< PC Class undefined */
|
||||
#define CLASS_MAGIC_USER 0 /**< PC Class Magic User */
|
||||
|
@ -280,7 +285,7 @@
|
|||
#define AFF_SENSE_LIFE 6 /**< Char can sense hidden life */
|
||||
#define AFF_WATERWALK 7 /**< Char can walk on water */
|
||||
#define AFF_SANCTUARY 8 /**< Char protected by sanct */
|
||||
#define AFF_GROUP 9 /**< (R) Char is grouped */
|
||||
#define AFF_UNUSED 9 /**< (R) Char is grouped */
|
||||
#define AFF_CURSE 10 /**< Char is cursed */
|
||||
#define AFF_INFRAVISION 11 /**< Char can see in dark */
|
||||
#define AFF_POISON 12 /**< (R) Char is poisoned */
|
||||
|
@ -804,6 +809,8 @@ struct room_data
|
|||
struct script_data *script; /**< script info for the room */
|
||||
struct obj_data *contents; /**< List of items in room */
|
||||
struct char_data *people; /**< List of NPCs / PCs in room */
|
||||
|
||||
struct list_data * events;
|
||||
};
|
||||
|
||||
/* char-related structures */
|
||||
|
@ -835,6 +842,15 @@ struct time_data
|
|||
int played; /**< This is the total accumulated time played in secs */
|
||||
};
|
||||
|
||||
/* Group Data Struct */
|
||||
struct group_data
|
||||
{
|
||||
struct char_data * leader;
|
||||
struct list_data * members;
|
||||
int group_flags;
|
||||
};
|
||||
|
||||
|
||||
/** The pclean_criteria_data is set up in config.c and used in db.c to determine
|
||||
* the conditions which will cause a player character to be deleted from disk
|
||||
* if the automagic pwipe system is enabled (see config.c). */
|
||||
|
@ -1035,6 +1051,8 @@ struct char_data
|
|||
struct follow_type *followers; /**< List of characters following */
|
||||
struct char_data *master; /**< List of character being followed */
|
||||
|
||||
struct group_data *group; /**< Character's Group */
|
||||
|
||||
long pref; /**< unique session id */
|
||||
|
||||
struct list_data * events;
|
||||
|
|
|
@ -573,7 +573,6 @@ void stop_follower(struct char_data *ch)
|
|||
|
||||
ch->master = NULL;
|
||||
REMOVE_BIT_AR(AFF_FLAGS(ch), AFF_CHARM);
|
||||
REMOVE_BIT_AR(AFF_FLAGS(ch), AFF_GROUP);
|
||||
}
|
||||
|
||||
/** Finds the number of follows that are following, and charmed by, the
|
||||
|
|
|
@ -867,6 +867,11 @@ do \
|
|||
/** Defines if ch is outdoors or not. */
|
||||
#define OUTSIDE(ch) (!ROOM_FLAGGED(IN_ROOM(ch), ROOM_INDOORS))
|
||||
|
||||
/* Group related defines */
|
||||
#define GROUP(ch) (ch->group)
|
||||
#define GROUP_LEADER(group) (group->leader)
|
||||
#define GROUP_FLAGS(group) (group->group_flags)
|
||||
|
||||
/* Happy-hour defines */
|
||||
#define IS_HAPPYQP (happy_data.qp_rate > 0)
|
||||
#define IS_HAPPYEXP (happy_data.exp_rate > 0)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue