/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DIRT 3.0.x (Version of AberMUD) * * * * Written : James Willie (Ithor) 1993. * * * * File: The module handles this to do with grouping of players. This * * includes both putting them in and out of groups, following the leader * * of the group etc. Grouped players will share the points gained by the * * death blow amongst other things. * * * * PROMOTE : promote(); GTELL : gtell(); GROUP : group() * * REPORT : reportcom(); GLIST : glist(); * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "kernel.h" #include "mudmacros.h" #include "exits.h" #include "pflags.h" #include "mflags.h" #include "sflags.h" #include "oflags.h" #include "lflags.h" #include "quests.h" #include "cflags.h" #include "levels.h" #include "locations.h" #include "timing.h" #include "sendsys.h" #include "objects.h" #include "mobiles.h" #include "mobile.h" #include "fight.h" #include "group.h" #include "bprintf.h" #include "log.h" #include "mud.h" #include "move.h" /* ** report tells you and any player in same group as you your score and ** strength. Optional, it may also tell all those in same room as you too. ** See group.h */ void reportcom() { int i; char buf[80]; if (aliased(real_mynum)) { bprintf("Not while aliased.\n"); return; } else if (pgrouped(mynum) == -1) { bprintf("You're not part of any group.\n"); return; } sprintf (buf, "&+Ystrength: %3d/%-3d, mana: %2d/%-2d, score: %d&N", pstr(mynum), maxstrength(mynum), pmagic(mynum), maxmagic(mynum), pscore(mynum)); bprintf ("You report '%s'\n",buf); #if (REPORT_WHO >= 1) send_msg (ploc(mynum), MODE_NODEAF, LVL_MIN, LVL_MAX, mynum, NOBODY, "\001p%s\003 reports '%s'\n", pname(mynum), buf); #endif #if (REPORT_WHO <= 1) for (i = 0; i < max_players; i++) { if (is_in_game(i) && (pgrouped(i) == pgrouped(mynum)) && (i != mynum)) { #if (REPORT_WHO == 1) if (ploc(i) != ploc(mynum)) #endif #if (REPORT_WHO == 0) if (ploc(i) == (ploc(mynum)) #endif sendf(i, "%s reports '%s'\n", pname(mynum), buf); } } #endif return; } /* ** Do not know if this is really useful to awiz+, but is for debugging. ** May choose to let wiz's use this, but the undefine SRGD. That info ** will only confuse anyone who don't know what it is. */ void glist() { int i,j,k; int groups[max_players*2]; /* worst situation is max_player groups of 1 */ /* player each requiring extra 32 nums to sep */ if(plev(mynum) < LVL_ARCHWIZARD)/* Min level can use this. Suggest LVL_AWIZ */ { bprintf("Pardon?\n"); return; } #ifdef SHOW_RAW_GROUP_DATA bprintf("The data format is\n [player_slot_number(i),rplrs[i].grouped," "rplrs[i].i_follow].\n"); #endif k = 0; for(i = 0; i < max_players; i++) { #ifdef SHOW_RAW_GROUP_DATA if ((i % 4) == 0) /* May be raw debugging info, but no need to be sloppy */ bprintf("\n"); bprintf("[%3d, %3d, %3d] ", i, pgrouped(i), pfollow(i)); #endif if (pgrouped(i) == i) { groups[k++] = -1; groups[k++] = i; for (j = 0; j < max_players; j++) if (is_in_game(j) && (i != j) && (pgrouped(j) == i)) groups[k++] = j; } } if (k < 2) /* smallest possible if any group existed */ { bprintf("\n\tThe are No players in the game grouped.\n"); return; } j = 1; for (i = 0; i < k; i++) { if(groups[i] == -1) { bprintf("\n&+gGROUP %d: Leader = %s\n", j, pname(groups[i+1])); j++; } else bprintf("\t%s ",pname(groups[i])); } bprintf("\n\n\tThere are %d groups in the game.\n",(j-1)); return; } /* ** This takes care of grouping players and ungrouping them when requested. ** (It will toggle players grouped status, but calls ungroup() to actually ** do the ungrouping. If group is called from the mud with no argument then ** it will display the details of the group to which ** mynum ** currently ** belongs. Note also that only a group leader can group others and they must ** follow them first. */ void group() { int i; if (pfighting(mynum) != -1) { bprintf("Not in a fight!\n"); return; } if (EMPTY(item1)) /* We want to see who is in our group */ { if (pgrouped(mynum) == -1) { bprintf("You are not grouped.\n"); return; } bprintf("%-*s [cur_str/max_str] [Vis] [Level] [Score]\n",PNAME_LEN + 3, "NAME"); for (i = 0; i < max_players; i++) if (is_in_game(i) && pgrouped(i) == pgrouped(mynum)) bprintf("%-*s [%7d/%7d] [%5d] [%5d] [%d] %s\n",PNAME_LEN+3, pname(i), pstr(i), maxstrength(i), pvis(i), plev(i), pscore(i), ((pgrouped(i) == i) ? "(Leader)" : " ")); return; } /* Ok, we want to add item1 to our group */ if ((pl1 == -1) || (plev(mynum) < pvis(pl1))) bprintf("Group with who?\n"); else if (pl1 >= max_players) bprintf("You can't group a monster.\n"); else if (pgrouped(pl1) == mynum) ungroup(pl1); else if (pgrouped(mynum) == -1) { if (mynum == pl1) { pgrouped(pl1) = mynum; bprintf("You group yourself.\n"); return; } bprintf("You have to group yourself first.\n"); } else if (pgrouped(mynum) != mynum) bprintf("You are grouped with someone already. [use lose to leave]\n"); else if (pfollow(pl1) != mynum) bprintf("%s is not following you.\n",pname(pl1)); else /* Ok, lets group pl1 */ { pgrouped(pl1) = mynum; bprintf("Ok\n"); sendf(pl1, "You are now a group member. [Leader %s]\n",pname(mynum)); if (mynum != pl1) mudlog("GROUP: %s has joined %s.",pname(pl1), pname(mynum)); } return; } /* ** ungroups player pl, and the whole group if pl was the leader. */ void ungroup(int pl) { int i; if (pgrouped(pl) == -1) return; if (pl == mynum) /* ungroup the leader and everyone grouped to them */ { for(i = 0; i < max_players; i++) if (is_in_game(i) && (pgrouped(i) == mynum) && (i != pl)) ungroup(i); } pgrouped(pl) = -1; sendf(pl,"You are no longer grouped.\n"); return; } /* ** TELL <msg> to all the members of my group. Note that visibility, s,p,m or ** lflags make no difference here. Invisible players will have their names ** seen by the group. */ void gtell() { int b, leader; char buf[80]; if ((leader = is_grouped(mynum)) == -1) { bprintf("Your not grouped with anyone.\n"); return; } if (EMPTY(txt1)) { bprintf("What do you want to tell them?\n"); return; } for (b = 0; b < max_players; b++) { if (is_in_game(b) && leader == is_grouped(b)) { if (b == mynum) sprintf(buf,"You tell the group, "); else sprintf(buf,"%s tells the group, ", pname(mynum)); sendf(b, "%s&+M\"&+m%s&+M\"\n", buf, txt1); } } return; } /* ** This will decide fi members of a group should follow their leader and ** cause them to if they should. Or try to in somecases. */ void check_group_leader(int lloc, int dir) { int i; int me, rme; if (is_grouped(mynum) != mynum) return; me = mynum; rme = real_mynum; for (i = 0; i < max_players; i++) { if (i != me && is_grouped(i) == me && ploc(i) == lloc) { setup_globals(i); sendf(i,"You follow %s.\n",pname(me)); dodirn(False, dir+2); } } setup_globals(rme); return; } /* ** Promote another member of your group to leader */ void promote() { int i; if (is_grouped(mynum) != mynum) { bprintf("You do not lead a group.\n"); return; } if ((pl1 == -1) || (mynum != is_grouped(pl1))) { bprintf("Promote who to leader? You must specify another group member.\n"); return; } for (i = 0; i < max_players; i++) { if (is_in_game(i) && mynum == is_grouped(i)) { pgrouped(i) = pl1; sendf(i,"The new group leader is %s.\n",pname(pl1)); } } return; } /* ** kill_bonus() just shares the points awarded for the death blow, amongst ** the group. See group.h for some configuration. ** ** BONUS_FACTOR_DAM : Default is 10, as was in origional dirt3.0 ** BONUS_FACTOR_ARMOR : Default 5. Extra bonus for armored mobs. ** BONUS_PER_MEMBER : Xtra % bonus added to score gain / group member. ** MAX_BONUS : Maximum bonus to be added as %. ** */ void kill_bonus(int a, int v) { int i, leader; int xp,x; if (v < max_players) /* v is a player */ xp = ((plev(v) > 4) ? (plev(v)*plev(v)*plev(v)*10) : 0); else xp = (BONUS_FACTOR_DAM * pdam(v)) + (BONUS_FACTOR_ARMOR * parmor(v)); x = 0; if ((leader = is_grouped(a)) >= 0) { for(i = 0; i < max_players; i++) x += (((is_grouped(i) == leader) && (ploc(a) == ploc(i))) ? 1 : 0); /* add % to xp */ xp += ((xp * (min(MAX_BONUS, (x * BONUS_PER_MEMBER)))) / 100); for (i = 0; i < max_players; i++) if ((leader == is_grouped(i)) && (ploc(i) == ploc(a))) setpscore(i, pscore(i) + xp/x); } else setpscore(a, pscore(a) + xp); return; }