ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/compat.C
(Generate patch)

Comparing deliantra/server/common/compat.C (file contents):
Revision 1.1 by root, Wed Nov 4 00:02:47 2009 UTC vs.
Revision 1.12 by root, Thu Apr 29 17:43:26 2010 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 6 * Copyright (©) 1992 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * the terms of the Affero GNU General Public License as published by the 9 * the terms of the Affero GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your 10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
34 34
35#include <global.h> 35#include <global.h>
36#include "define.h" 36#include "define.h"
37#include "path.h" 37#include "path.h"
38 38
39
40/* buf_overflow() - we don't want to exceed the buffer size of 39/* buf_overflow() - we don't want to exceed the buffer size of
41 * buf1 by adding on buf2! Returns true if overflow will occur. 40 * buf1 by adding on buf2! Returns true if overflow will occur.
42 */ 41 */
43int 42int
44buf_overflow (const char *buf1, const char *buf2, int bufsize) 43buf_overflow (const char *buf1, const char *buf2, int bufsize)
53 52
54 if ((len1 + len2) >= bufsize) 53 if ((len1 + len2) >= bufsize)
55 return 1; 54 return 1;
56 55
57 return 0; 56 return 0;
58}
59
60/////////////////////////////////////////////////////////////////////////////
61
62static const char *const fatalmsgs[80] = {
63 "Failed to allocate memory",
64 "Failed repeatedly to load maps",
65 "Hashtable for archetypes is too small",
66 "Too many errors"
67};
68
69/*
70 * fatal() is meant to be called whenever a fatal signal is intercepted.
71 * It will call the emergency_save and the clean_tmp_files functions.
72 */
73void
74fatal (int err)
75{
76 LOG (llevError, "Fatal: %s\n", fatalmsgs [err]);
77 cleanup (fatalmsgs[err], 1);
78} 57}
79 58
80///////////////////////////////////////////////////////////////////////////// 59/////////////////////////////////////////////////////////////////////////////
81 60
82/* 61/*
93 * and if goodbad is non-zero, luck increases the roll, if zero, it decreases. 72 * and if goodbad is non-zero, luck increases the roll, if zero, it decreases.
94 * Generally, op should be the player/caster/hitter requesting the roll, 73 * Generally, op should be the player/caster/hitter requesting the roll,
95 * not the recipient (ie, the poor slob getting hit). [garbled 20010916] 74 * not the recipient (ie, the poor slob getting hit). [garbled 20010916]
96 */ 75 */
97int 76int
98random_roll (int r_min, int r_max, const object *op, int goodbad) 77random_roll (int r_min, int r_max, const object *op, bool prefer_high)
99{ 78{
100 r_max = max (r_min, r_max); 79 r_max = max (r_min, r_max);
101 80
102 int base = r_max - r_min > 1 ? 20 : 50; /* d2 and d3 are corner cases */ 81 int base = r_max - r_min > 1 ? 20 : 50; /* d2 and d3 are corner cases */
103 82
117/* 96/*
118 * This is a 64 bit version of random_roll above. This is needed 97 * This is a 64 bit version of random_roll above. This is needed
119 * for exp loss calculations for players changing religions. 98 * for exp loss calculations for players changing religions.
120 */ 99 */
121sint64 100sint64
122random_roll64 (sint64 r_min, sint64 r_max, const object *op, int goodbad) 101random_roll64 (sint64 r_min, sint64 r_max, const object *op, bool prefer_high)
123{ 102{
124 sint64 omin = r_min;
125 sint64 range = max (0, r_max - r_min + 1); 103 sint64 range = max (0, r_max - r_min + 1);
126 int base = range > 2 ? 20 : 50; /* d2 and d3 are corner cases */ 104 int base = range > 2 ? 20 : 50; /* d2 and d3 are corner cases */
127 105
128 /* 106 /*
129 * Make a call to get two 32 bit unsigned random numbers, and just to 107 * Make a call to get two 32 bit unsigned random numbers, and just do
130 * a little bitshifting. 108 * a little bitshifting.
131 */ 109 */
132 sint64 ran = (sint64) rndm.next () ^ ((sint64) rndm.next () << 31); 110 sint64 ran = (sint64) rndm.next () ^ ((sint64) rndm.next () << 31);
133 111
134 if (op->type != PLAYER) 112 if (op->stats.luck)
135 return ((ran % range) + r_min); 113 {
136
137 int luck = op->stats.luck; 114 int luck = op->stats.luck;
138 115
139 if (rndm (base) < min (10, abs (luck))) 116 if (rndm (base) < min (10, abs (luck)))
140 { 117 {
141 /* we have a winner */ 118 /* we have a winner */
142 ((luck > 0) ? (luck = 1) : (luck = -1)); 119 luck = luck > 0 ? 1 : -1;
120
143 range -= luck; 121 range -= luck;
144 if (range < 1) 122 if (range < 1)
145 return (omin); /*check again */ 123 return r_min; /*check again */
146 124
147 ((goodbad) ? (r_min += luck) : (range)); 125 if (prefer_high)
126 r_min += luck;
148 127
149 return (max (omin, min (r_max, (ran % range) + r_min))); 128 return clamp (ran % range + r_min, r_min, r_max);
129 }
150 } 130 }
151 131
152 return ran % range + r_min; 132 return ran % range + r_min;
153} 133}
154 134
158 * Generally, op should be the player/caster/hitter requesting the roll, 138 * Generally, op should be the player/caster/hitter requesting the roll,
159 * not the recipient (ie, the poor slob getting hit). 139 * not the recipient (ie, the poor slob getting hit).
160 * The args are num D size (ie 4d6) [garbled 20010916] 140 * The args are num D size (ie 4d6) [garbled 20010916]
161 */ 141 */
162int 142int
163die_roll (int num, int size, const object *op, int goodbad) 143die_roll (int num, int size, const object *op, bool prefer_high)
164{ 144{
165 int min, luck, total, i, gotlucky; 145 int min_roll, luck, total, i, gotlucky;
166 146
167 int diff = size; 147 int diff = size;
168 min = 1; 148 min_roll = 1;
169 luck = total = gotlucky = 0; 149 luck = total = gotlucky = 0;
170 int base = diff > 2 ? 20 : 50; /* d2 and d3 are corner cases */ 150 int base = diff > 2 ? 20 : 50; /* d2 and d3 are corner cases */
171 151
172 if (size < 2 || diff < 1) 152 if (size < 2 || diff < 1)
173 { 153 {
174 LOG (llevError, "Calling die_roll with num=%d size=%d\n", num, size); 154 LOG (llevError | logBacktrace, "Calling die_roll with num=%d size=%d\n", num, size);
175 return num; /* avoids a float exception */ 155 return num; /* avoids a float exception */
176 } 156 }
177 157
178 if (op->type == PLAYER) 158 if (op->type == PLAYER)
179 luck = op->stats.luck; 159 luck = op->stats.luck;
180 160
181 for (i = 0; i < num; i++) 161 for (i = 0; i < num; i++)
182 { 162 {
183 if (rndm (base) < MIN (10, abs (luck)) && !gotlucky) 163 if (rndm (base) < min (10, abs (luck)) && !gotlucky)
184 { 164 {
185 /* we have a winner */ 165 /* we have a winner */
186 gotlucky++; 166 gotlucky++;
187 ((luck > 0) ? (luck = 1) : (luck = -1)); 167 ((luck > 0) ? (luck = 1) : (luck = -1));
188 diff -= luck; 168 diff -= luck;
189 if (diff < 1) 169 if (diff < 1)
190 return (num); /*check again */ 170 return (num); /*check again */
191 ((goodbad) ? (min += luck) : (diff)); 171 ((prefer_high) ? (min_roll += luck) : (diff));
192 total += MAX (1, MIN (size, rndm (diff) + min)); 172 total += max (1, min (size, rndm (diff) + min_roll));
193 } 173 }
194 else 174 else
195 total += rndm (size) + 1; 175 total += rndm (size) + 1;
196 } 176 }
197 177
233 } 213 }
234 214
235 return path; 215 return path;
236} 216}
237 217
238void 218static void
239path_normalize (char *path) 219path_normalize (char *path)
240{ 220{
241 char *p; /* points to the beginning of the path not yet processed; this is 221 char *p; /* points to the beginning of the path not yet processed; this is
242 either a path component or a path separator character */ 222 either a path component or a path separator character */
243 char *q; /* points to the end of the path component p points to */ 223 char *q; /* points to the end of the path component p points to */
314 path = path_combine (src, dst); 294 path = path_combine (src, dst);
315 path_normalize (path); 295 path_normalize (path);
316 return (path); 296 return (path);
317} 297}
318 298
319char *
320strcasestr_local (const char *s, const char *find)
321{
322 char c, sc;
323 size_t len;
324
325 if ((c = *find++) != 0)
326 {
327 c = tolower (c);
328 len = strlen (find);
329 do
330 {
331 do
332 {
333 if ((sc = *s++) == 0)
334 return NULL;
335 }
336 while (tolower (sc) != c);
337 }
338 while (strncasecmp (s, find, len) != 0);
339 s--;
340 }
341 return (char *) s;
342}
343
344/**
345 * open_and_uncompress() first searches for the original filename. If it exist,
346 * then it opens it and returns the file-pointer.
347 */
348FILE *
349open_and_uncompress (const char *name, int flag, int *compressed)
350{
351 *compressed = 0;
352 return fopen (name, "r");
353}
354
355/*
356 * See open_and_uncompress().
357 */
358
359void
360close_and_delete (FILE * fp, int compressed)
361{
362 fclose (fp);
363}
364
365/*
366 * Strip out the media tags from a String.
367 * Warning the input string will contain the result string
368 */
369void
370strip_media_tag (char *message)
371{
372 int in_tag = 0;
373 char *dest;
374 char *src;
375
376 src = dest = message;
377 while (*src != '\0')
378 {
379 if (*src == '[')
380 {
381 in_tag = 1;
382 }
383 else if (in_tag && (*src == ']'))
384 in_tag = 0;
385 else if (!in_tag)
386 {
387 *dest = *src;
388 dest++;
389 }
390 src++;
391 }
392 *dest = '\0';
393}
394
395const char *
396strrstr (const char *haystack, const char *needle)
397{
398 const char *lastneedle;
399
400 lastneedle = NULL;
401 while ((haystack = strstr (haystack, needle)) != NULL)
402 {
403 lastneedle = haystack;
404 haystack++;
405 }
406 return lastneedle;
407
408}
409
410#define EOL_SIZE (sizeof("\n")-1) 299#define EOL_SIZE (sizeof("\n")-1)
411void 300void
412strip_endline (char *buf) 301strip_endline (char *buf)
413{ 302{
414 if (strlen (buf) < sizeof ("\n")) 303 if (*buf && buf [strlen (buf) - 1] == '\n')
415 {
416 return;
417 }
418 if (!strcmp (buf + strlen (buf) - EOL_SIZE, "\n"))
419 buf[strlen (buf) - EOL_SIZE] = '\0'; 304 buf [strlen (buf) - 1] = '\0';
420} 305}
421 306
422/** 307/**
423 * Replace in string src all occurrences of key by replacement. The resulting 308 * Replace in string src all occurrences of key by replacement. The resulting
424 * string is put into result; at most resultsize characters (including the 309 * string is put into result; at most resultsize characters (including the

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines