ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/modules/gameserv/dice.C
Revision: 1.2
Committed: Sat Jul 21 01:29:09 2007 UTC (19 years, 2 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.1: +3 -3 lines
Log Message:
- moved to new documentation system
- fixed small build error

File Contents

# User Rev Content
1 pippijn 1.1 /*
2     * Copyright © 2005-2007 William Pitcock <nenolod@nenolod.net>
3     * Copyright © 2006-2007 Jilles Tjoelker <jilles@stack.nl>
4     *
5 pippijn 1.2 * Rights to this code are documented in doc/pod/license.pod.
6 pippijn 1.1 *
7     * Dice generator.
8     *
9 pippijn 1.2 * $Id: dice.C,v 1.1 2007-07-19 08:24:53 pippijn Exp $
10 pippijn 1.1 */
11    
12     #include "atheme.h"
13    
14     static char const rcsid[] = "$Id";
15    
16     struct gs_dice_listeners : callback::has_listeners
17     {
18     };
19    
20     gs_dice_listeners listeners;
21    
22 pippijn 1.2 DECLARE_MODULE_V1 ("gameserv/dice", false, _modinit, _moddeinit, "$Id: dice.C,v 1.1 2007-07-19 08:24:53 pippijn Exp $", "The Ermyth Team <http://ermyth.schmorp.de>");
23 pippijn 1.1
24     static void command_dice (sourceinfo_t *si, int parc, char *parv[]);
25     static void command_wod (sourceinfo_t *si, int parc, char *parv[]);
26     static void command_df (sourceinfo_t *si, int parc, char *parv[]);
27    
28     command_t cmd_dice = { "ROLL", N_("Rolls one or more dice."), AC_NONE, 2, command_dice };
29     command_t cmd_wod = { "WOD", N_("WOD-style dice generation."), AC_NONE, 7, command_wod };
30     command_t cmd_df = { "DF", N_("Fudge-style dice generation."), AC_NONE, 2, command_df };
31    
32     cmdvec *gs_cmdtree;
33     cmdvec *cs_cmdtree;
34    
35     helpvec *gs_helptree;
36     helpvec *cs_helptree;
37    
38     void
39     _modinit (module_t *m)
40     {
41     MODULE_USE_SYMBOL_T (gs_cmdtree, cmdvec, "gameserv/main", "gs_cmdtree");
42     MODULE_USE_SYMBOL_T (cs_cmdtree, cmdvec, "chanserv/main", "cs_cmdtree"); /* fantasy commands */
43    
44     MODULE_USE_SYMBOL_T (gs_helptree, helpvec, "gameserv/main", "gs_helptree");
45     MODULE_USE_SYMBOL_T (cs_helptree, helpvec, "chanserv/main", "cs_helptree"); /* fantasy commands */
46    
47     gs_cmdtree << cmd_dice;
48     gs_cmdtree << cmd_wod;
49     gs_cmdtree << cmd_df;
50    
51     cs_cmdtree << cmd_dice;
52     cs_cmdtree << cmd_wod;
53     cs_cmdtree << cmd_df;
54    
55     help_addentry (gs_helptree, "ROLL", "help/gameserv/roll", NULL);
56     help_addentry (cs_helptree, "ROLL", "help/gameserv/roll", NULL);
57     }
58    
59     void
60     _moddeinit ()
61     {
62     gs_cmdtree >> cmd_dice;
63     gs_cmdtree >> cmd_wod;
64     gs_cmdtree >> cmd_df;
65    
66     cs_cmdtree >> cmd_dice;
67     cs_cmdtree >> cmd_wod;
68     cs_cmdtree >> cmd_df;
69    
70     help_delentry (gs_helptree, "ROLL");
71     help_delentry (cs_helptree, "ROLL");
72     }
73    
74     /*
75     * Handle reporting for both fantasy commands and normal commands in GameServ
76     * quickly and easily. Of course, sourceinfo has a vtable that can be manipulated,
77     * but this is quicker and easier... -- nenolod
78     */
79     static void
80     gs_command_report (sourceinfo_t *si, char *fmt, ...)
81     {
82     va_list args;
83     char buf[BUFSIZE];
84    
85     va_start (args, fmt);
86     vsnprintf (buf, BUFSIZE, fmt, args);
87     va_end (args);
88    
89     if (si->c != NULL)
90     msg (chansvs.nick, si->c->name, "%s", buf);
91     else
92     command_success_nodata (si, "%s", buf);
93     }
94    
95     static void
96     command_dice (sourceinfo_t *si, int parc, char *parv[])
97     {
98     char *arg = si->c != NULL ? parv[1] : parv[0];
99     int dice = 0, sides = 0, i = 0, roll = 0, modifier = 0;
100     char buf[BUFSIZE];
101    
102     if (!arg)
103     return;
104     sscanf (arg, "%dd%d+%d", &dice, &sides, &modifier);
105    
106     if (dice <= 0)
107     {
108     modifier = 0;
109     sscanf (arg, "%dd%d", &dice, &sides);
110    
111     if (dice <= 0)
112     {
113     dice = 1;
114    
115     sscanf (arg, "d%d+%d", &sides, &modifier);
116    
117     if (sides <= 0)
118     sscanf (arg, "d%d", &sides);
119     }
120     }
121    
122     if (dice > 100)
123     dice = 100;
124     if (sides > 100)
125     sides = 100;
126    
127     if (dice <= 0 || sides <= 0)
128     {
129     dice = 1;
130     sides = 1;
131     }
132    
133     *buf = '\0';
134    
135     for (i = 0; i < dice; i++)
136     {
137     unsigned int y = 1 + arc4random () % sides;
138     char buf2[BUFSIZE];
139    
140     if (*buf != '\0')
141     {
142     snprintf (buf2, BUFSIZE, ", %d", y);
143     strlcat (buf, buf2, BUFSIZE);
144     }
145     else
146     {
147     snprintf (buf2, BUFSIZE, "%d", y);
148     strlcpy (buf, buf2, BUFSIZE);
149     }
150    
151     roll += y;
152     }
153    
154     if (modifier != 0)
155     gs_command_report (si, "(%s) + %d == \2%d\2", buf, modifier, (roll + modifier));
156     else
157     gs_command_report (si, "%s == \2%d\2", buf, roll);
158     }
159    
160     static void
161     command_wod (sourceinfo_t *si, int parc, char *parv[])
162     {
163     int ii = si->c != NULL ? 1 : 0;
164     char *arg_dice = parv[ii++];
165     char *arg_difficulty = parv[ii++];
166    
167     int dice, difficulty;
168     int roll, total = 0, roll_count = 0, i;
169     int success = 0, failure = 0, botches = 0, rerolls = 0;
170    
171     static char buf[BUFSIZE];
172     char *end_p;
173    
174     if (arg_dice == NULL || arg_difficulty == NULL)
175     {
176     command_fail (si, fault_needmoreparams, _("Syntax: WOD <dice> <difficulty>"));
177     return;
178     }
179    
180     while (roll_count < 3 && arg_dice != NULL && arg_difficulty != NULL)
181     {
182     total = 0, success = 0, failure = 0, botches = 0, rerolls = 0;
183     roll_count++;
184    
185     dice = atoi (arg_dice);
186     difficulty = atoi (arg_difficulty);
187    
188     if (dice > 30 || dice < 1)
189     {
190     command_fail (si, fault_badparams, _("Only 1-30 dice may be thrown at one time."));
191     return;
192     }
193     else if (difficulty > 10 || difficulty < 1)
194     {
195     command_fail (si, fault_badparams, _("Difficulty setting must be between 1 and 10."));
196     return;
197     }
198     else
199     {
200     end_p = buf;
201    
202     for (i = 0; i < dice; i++)
203     {
204     roll = (arc4random () % 10) + 1;
205    
206     end_p += snprintf (end_p, BUFSIZE - (end_p - buf), "%d ", roll);
207    
208     if (roll == 1)
209     {
210     botches++;
211     continue;
212     }
213     else if (roll == 10)
214     rerolls++;
215    
216     if (roll >= difficulty)
217     success++;
218     else
219     failure++;
220     }
221    
222     rerolls = rerolls - botches;
223     total = success - botches;
224    
225     gs_command_report (si, _("%s rolls %d dice at difficulty %d: %s"), si->su->nick, dice, difficulty, buf);
226    
227     if (rerolls > 0)
228     gs_command_report (si, _("Successes: %d, Failures: %d, Botches: %d, Total: %d. You may reroll %d if you have a specialty."), success, failure, botches, total, rerolls);
229     else
230     gs_command_report (si, _("Successes: %d, Failures: %d, Botches: %d, Total: %d."), success, failure, botches, total);
231     }
232    
233     /* prepare for another go. */
234     arg_dice = parv[ii++];
235     arg_difficulty = parv[ii++];
236     }
237     }
238    
239     static char *df_dice_table[3] = { "[-]", "[ ]", "[+]" };
240    
241     static void
242     command_df (sourceinfo_t *si, int parc, char *parv[])
243     {
244     int ii = si->c != NULL ? 1 : 0;
245     char *arg_dice = parv[ii++];
246     char buf[BUFSIZE];
247     int i, dice;
248    
249     if (arg_dice == NULL)
250     {
251     command_fail (si, fault_needmoreparams, _("Syntax: DF <dice>"));
252     return;
253     }
254    
255     dice = atoi (arg_dice);
256     *buf = '\0';
257    
258     if (dice > 30 || dice < 1)
259     {
260     command_fail (si, fault_badparams, _("Only 1-30 dice may be thrown at one time."));
261     return;
262     }
263    
264     for (i = 0; i < dice; i++)
265     {
266     int roll = arc4random () % 3;
267    
268     if (*buf != '\0')
269     strlcat (buf, df_dice_table[roll], BUFSIZE);
270     else
271     strlcpy (buf, df_dice_table[roll], BUFSIZE);
272     }
273    
274     gs_command_report (si, _("Result: %s"), buf);
275     }
276    
277     /* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs
278     * vim:ts=8
279     * vim:sw=8
280     * vim:noexpandtab
281     */