/* * GroupNew: Create a new group with the given name. * Return True if group created. */ Bool GroupNew(char *group_name) { int i; UserGroup g; if (num_groups >= MAX_NUMGROUPS) { GameMessage(GetString(hInst, IDS_TOOMANYGROUPS)); return FALSE; } // Search for exact duplicate for (i=0; i < num_groups; i++) if (!stricmp(group_name, groups[i])) { GameMessage(GetString(hInst, IDS_ALREADYGROUP)); return False; } // Add group to list strncpy(groups[num_groups], group_name, MAX_GROUPNAME); groups[num_groups][MAX_GROUPNAME] = 0; num_groups++; g.num_users = 0; GroupSave(group_name, &g); return True; }
/* * GroupDelete: Remove the group with the given name. * Return True on success. */ Bool GroupDelete(char *group_name) { int index, i; index = FindGroupByName(group_name); switch(index) { case GROUP_NOMATCH: GameMessage(GetString(hInst, IDS_BADGROUPNAME)); return False; case GROUP_AMBIGUOUS: GameMessage(GetString(hInst, IDS_DUPLICATEGROUPNAME)); return False; } group_name = groups[index]; // Remove INI entry WritePrivateProfileString(group_section, group_name, NULL, cinfo->ini_file); // Remove group from internal group structure for (i=index; i < num_groups - 1; i++) strcpy(groups[i], groups[i + 1]); num_groups--; return True; }
/* * GroupAdd: Add the names in args to the given group name. If the group doesn't * exist, create it. * Return number of names added to group (0 on failure). */ int GroupAdd(char *group_name, char *args) { UserGroup g; int index, i, num_added; char *ptr, *name; Bool add_name; num_added = 0; index = FindGroupByName(group_name); switch(index) { case GROUP_NOMATCH: GameMessage(GetString(hInst, IDS_BADGROUPNAME)); return 0; case GROUP_AMBIGUOUS: GameMessage(GetString(hInst, IDS_DUPLICATEGROUPNAME)); return 0; default: group_name = groups[index]; GroupLoad(group_name, &g); break; } name = GetPlayerName(args, &ptr); while (name != NULL) { if (g.num_users >= MAX_GROUPSIZE) { GameMessagePrintf(GetString(hInst, IDS_GROUPFULL), MAX_GROUPNAME, group_name); break; } // Check for duplicates add_name = True; for (i=0; i < g.num_users; i++) if (!stricmp(g.names[i], name)) { add_name = False; break; } if (add_name) { strncpy(g.names[g.num_users], name, MAX_CHARNAME); g.names[g.num_users][MAX_CHARNAME] = 0; g.num_users++; num_added++; } name = GetPlayerName(ptr, &ptr); } GroupSave(group_name, &g); return num_added; }
/* * GroupDeleteNames: Remove the given names from the given group. * Return number of names deleted, or -1 if the group itself was deleted. */ int GroupDeleteNames(char *group_name, char *args) { int i, j, index, num_deleted; UserGroup g; char *name, *ptr; index = FindGroupByName(group_name); switch(index) { case GROUP_NOMATCH: GameMessage(GetString(hInst, IDS_BADGROUPNAME)); return 0; case GROUP_AMBIGUOUS: GameMessage(GetString(hInst, IDS_DUPLICATEGROUPNAME)); return 0; default: group_name = groups[index]; break; } GroupLoad(group_name, &g); // Remove each name num_deleted = 0; name = GetPlayerName(args, &ptr); while (name != NULL) { for (i=0; i < g.num_users; i++) if (!stricmp(g.names[i], name)) { for (j=i; j < g.num_users - 1; j++) strcpy(g.names[j], g.names[j + 1]); g.num_users--; num_deleted++; break; } name = GetPlayerName(ptr, &ptr); } // XXX Don't delete empty groups (???) #if 0 if (g.num_users == 0) { GroupDelete(group_name); return -1; } #endif GroupSave(group_name, &g); return num_deleted; }
/* * GroupPrint: Display the members of the group with the given name. */ void GroupPrint(char *group_name) { UserGroup g; int i, index; COLORREF color; BYTE style; ID id; char buf[MAX_CHARNAME + 10]; index = FindGroupByName(group_name); switch (index) { case GROUP_NOMATCH: GameMessage(GetString(hInst, IDS_BADGROUPNAME)); break; case GROUP_AMBIGUOUS: GameMessage(GetString(hInst, IDS_DUPLICATEGROUPNAME)); break; default: group_name = groups[index]; GroupLoad(group_name, &g); GameMessagePrintf(GetString(hInst, IDS_GROUPMEMBERS), MAX_GROUPNAME, group_name); color = RGB(0, 0, 0); style = STYLE_NORMAL; EditBoxStartAdd(); for (i=0; i < g.num_users; i++) { if (i != 0) DisplayMessage(", ", color, style); id = FindPlayerByNameExact(g.names[i]); // Show player in red if logged on if (id == 0 || id == INVALID_ID) DisplayMessage(g.names[i], color, style); else { sprintf(buf, "~r%s~n", g.names[i]); DisplayMessage(buf, color, style); } } EditBoxEndAdd(); break; } }
/* * VerbAlias: "alias" command */ void CommandAliasCommon(char *args, DLGPROC pfnAliasDialogProc, int idDialog) { if (args && *args) { while (*args == ' ' || *args == '\t') args++; } // Arguments given. Try to define or remove a command alias. // if (args && *args) { char* pszVerb = args; char* pszCommand; pszCommand = strtok(args, " \t=\r\n"); pszCommand = strtok(NULL, "\r\n"); if (pszCommand && *pszCommand) { AddVerbAlias(pszVerb, pszCommand); GameMessage(GetString(hInst, IDS_CMDALIASDEFINED)); } else { RemoveVerbAlias(pszVerb); GameMessage(GetString(hInst, IDS_CMDALIASREMOVED)); } AliasSave(); return; } // No arguments. Do the default (hotkey) dialog. // if (IDOK == DialogBox(hInst, MAKEINTRESOURCE(idDialog), cinfo->hMain, pfnAliasDialogProc)) { AliasSave(); } }
/* * CommandGetPlayer: "getplayer" command */ void CommandGetPlayer(char *args) { ID player; char temp[MAXAMOUNT + 1]; if (*args == 0) return; player = FindPlayerByName(args); if (player == 0) { GameMessage(GetString(hInst, IDS_NOPLAYERNAME)); return; } if (player == INVALID_ID) { GameMessage(GetString(hInst, IDS_DUPLICATEPLAYERNAME)); return; } sprintf(temp, "%d", player); RequestDMCommand(DM_GET_PLAYER, temp); }
/* * GroupsPrint: Display a list of all defined groups. */ void GroupsPrint(void) { int i; COLORREF color; BYTE style; if (num_groups == 0) { GameMessage(GetString(hInst, IDS_NOGROUPS)); return; } GameMessage(GetString(hInst, IDS_GROUPLIST)); color = RGB(0, 0, 0); style = STYLE_NORMAL; EditBoxStartAdd(); for (i=0; i < num_groups; i++) { if (i != 0) DisplayMessage(", ", color, style); DisplayMessage(groups[i], color, style); } EditBoxEndAdd(); }
/* * CastCallback: Called when user selects target of spell. */ void CastCallback(ID id) { /* Make temporary list for sending to server */ temp_obj.id = id; temp_obj.temp_amount = 1; if (pinfo.resting) GameMessage(GetString(hInst, IDS_SPELLRESTING)); else RequestCast(use_spell, temp_list); if (UserMouselookIsEnabled()) { while (ShowCursor(FALSE) >= 0) ShowCursor(FALSE); } }
/* * SpellCast: User wants to cast given spell. */ void SpellCast(spell *sp) { if (GetPlayer()->viewID && (GetPlayer()->viewID != GetPlayer()->id)) { if (!(GetPlayer()->viewFlags & REMOTE_VIEW_CAST)) return; } /* If we don't need target, just cast spell */ if (sp->num_targets == 0) { RequestCast(sp->obj.id, NULL); return; } if( GetUserTargetID() != INVALID_ID ) { ID id = GetUserTargetID(); // User has target already selected. if (id == GetPlayer()->id || FindVisibleObjectById(id)) { /* Make temporary list for sending to server */ temp_obj.id = GetUserTargetID(); temp_obj.temp_amount = 1; RequestCast( sp->obj.id, temp_list ); } else // Target cannot be seen. GameMessage( GetString( hInst, IDS_TARGETNOTVISIBLEFORCAST ) ); return; } /* Get target object from user */ /* Save spell # */ use_spell = sp->obj.id; /* Register callback & select item */ GameSetState(GAME_SELECT); SetSelectCallback(CastCallback); if (UserMouselookIsEnabled()) { while (ShowCursor(TRUE) < 0) ShowCursor(TRUE); } }
/* * InterfaceAction: User wants to perform given action. Return True iff * action should be passed along for further processing. */ Bool InterfaceAction(int action, void *action_data) { POINT mouse; AREA a; room_contents_node *r; static int lastRestWarning = 0; if ((pinfo.resting || cinfo->effects->paralyzed) && (IsMoveAction(action) || IsAttackAction(action))) { // debug(("Can't do while resting\n")); return False; } switch (action) { case A_TARGETCLEAR: case A_TARGETSELF: case A_TARGETNEXT: case A_TARGETPREVIOUS: case A_ATTACK: UserAreaRedraw(); return True; break; case A_FORWARDFAST: // If too tired, don't run if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_FORWARD, NULL); return False; } break; case A_BACKWARDFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_BACKWARD, NULL); return False; } break; case A_SLIDELEFTFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDELEFT, NULL); return False; } break; case A_SLIDERIGHTFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDERIGHT, NULL); return False; } break; case A_SLIDELEFTFORWARDFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDELEFTFORWARD, NULL); return False; } break; case A_SLIDELEFTBACKWARDFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDELEFTBACKWARD, NULL); return False; } break; case A_SLIDERIGHTFORWARDFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDERIGHTFORWARD, NULL); return False; } break; case A_SLIDERIGHTBACKWARDFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDERIGHTBACKWARD, NULL); return False; } break; case A_CAST: UserCastSpell(); return False; case A_CASTSPELL: // action_data is pointer to spell if (GetPlayer()->viewID && (GetPlayer()->viewID != GetPlayer()->id)) { if (!(GetPlayer()->viewFlags & REMOTE_VIEW_CAST)) { GameMessage(GetString(hInst, IDS_SPELLPARALYZED)); return False; } } if (cinfo->effects->paralyzed) { GameMessage(GetString(hInst, IDS_SPELLPARALYZED)); return False; } if (pinfo.resting) { GameMessage(GetString(hInst, IDS_SPELLRESTING)); return False; } SpellCast((spell *) action_data); return False; case A_GO: if (pinfo.resting) return False; break; case A_ENDDRAG: // action_data is ID of object being dragged // See if user dragged object to inventory InventoryGetArea(&a); GetCursorPos(&mouse); ScreenToClient(cinfo->hMain, &mouse); if (!IsInArea(&a, mouse.x, mouse.y)) break; r = GetRoomObjectById((ID) action_data); if (r == NULL) break; // If a non-gettable container, try to get contents if ((r->obj.flags & OF_CONTAINER) && !(r->obj.flags & OF_GETTABLE)) RequestObjectContents((ID) action_data); else RequestPickup((ID) action_data); break; case A_TABFWD: return InterfaceTab((int) action_data, True); case A_TABBACK: return InterfaceTab((int) action_data, False); } return True; }
/* * ParseVerbAlias: User typed this. Reissue a command if it was an alias. */ BOOL ParseVerbAlias(char* pInput) { char accum[MAXSAY+1]; char* pVerb; char* pArgs; int iMatch = -1; BOOL bTie = FALSE; BOOL bInvalid; int i; if (!pInput || !*pInput) return FALSE; pInput = strdup(pInput); if (!pInput) return FALSE; pVerb = pInput; while (*pVerb == ' ' || *pVerb == '\t') pVerb++; pArgs = strtok(pVerb, " \t\r\n"); pArgs = strtok(NULL, "\r\n"); if (!pArgs) pArgs = ""; for (i = 0; i < _nVerbAliases; i++) { // if defined verb begins with typed verb, if (_apVerbAliases[i].verb[0]) { if (0 == strnicmp(_apVerbAliases[i].verb, pVerb, strlen(pVerb))) { if (iMatch >= 0) bTie = TRUE; iMatch = i; if (0 == stricmp(_apVerbAliases[i].verb, pVerb)) { bTie = FALSE; break; } } } } if (iMatch < 0) return FALSE; if (bTie) { GameMessage(GetString(hInst, IDS_AMBIGUOUSALIAS)); return TRUE; } // Find any ~~ in .text, replace it with pArgs. // pVerb = _apVerbAliases[iMatch].text; strcpy(accum, pVerb); { char* pBefore = pVerb; char* pAfter = strstr(pVerb, "~~"); if (pAfter && (strlen(pVerb)+strlen(pArgs) < MAXSAY)) { strcpy(accum+(pAfter-pBefore), pArgs); strcat(accum, pAfter+2); pVerb = accum; } } bInvalid = ModuleEvent(EVENT_TEXTCOMMAND, accum); if (bInvalid) GameMessage(GetString(hInst, IDS_INVALIDALIAS)); // Return TRUE if command found and handled. return TRUE; }