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.2 by root, Fri Nov 6 13:03:34 2009 UTC vs.
Revision 1.19 by root, Sat Nov 17 23:40:00 2018 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 (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team
4 * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 5 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team 6 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 7 * Copyright (©) 1992 Frank Tore Johansen
7 * 8 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 9 * 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 10 * 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 11 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version. 12 * option) any later version.
12 * 13 *
13 * This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 17 * GNU General Public License for more details.
17 * 18 *
18 * You should have received a copy of the Affero GNU General Public License 19 * You should have received a copy of the Affero GNU General Public License
19 * and the GNU General Public License along with this program. If not, see 20 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>. 21 * <http://www.gnu.org/licenses/>.
21 * 22 *
22 * The authors can be reached via e-mail to <support@deliantra.net> 23 * The authors can be reached via e-mail to <support@deliantra.net>
23 */ 24 */
24 25
25/* 26/*
26 * compatibility functions for older (GPL) source code parts 27 * compatibility functions for older (GPL) source code parts
34 35
35#include <global.h> 36#include <global.h>
36#include "define.h" 37#include "define.h"
37#include "path.h" 38#include "path.h"
38 39
39
40/* buf_overflow() - we don't want to exceed the buffer size of 40/* buf_overflow() - we don't want to exceed the buffer size of
41 * buf1 by adding on buf2! Returns true if overflow will occur. 41 * buf1 by adding on buf2! Returns true if overflow will occur.
42 */ 42 */
43int 43int
44buf_overflow (const char *buf1, const char *buf2, int bufsize) 44buf_overflow (const char *buf1, const char *buf2, int bufsize)
45{ 45{
53 53
54 if ((len1 + len2) >= bufsize) 54 if ((len1 + len2) >= bufsize)
55 return 1; 55 return 1;
56 56
57 return 0; 57 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} 58}
79 59
80///////////////////////////////////////////////////////////////////////////// 60/////////////////////////////////////////////////////////////////////////////
81 61
82/* 62/*
93 * and if goodbad is non-zero, luck increases the roll, if zero, it decreases. 73 * 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, 74 * Generally, op should be the player/caster/hitter requesting the roll,
95 * not the recipient (ie, the poor slob getting hit). [garbled 20010916] 75 * not the recipient (ie, the poor slob getting hit). [garbled 20010916]
96 */ 76 */
97int 77int
98random_roll (int r_min, int r_max, const object *op, int goodbad) 78random_roll (int r_min, int r_max, const object *op, bool prefer_high)
99{ 79{
100 r_max = max (r_min, r_max); 80 if (r_min > r_max)
81 swap (r_min, r_max);
101 82
83 int range = r_max - r_min + 1;
84 int num = rndm (r_min, r_max);
85
86 if (op->stats.luck)
87 {
102 int base = r_max - r_min > 1 ? 20 : 50; /* d2 and d3 are corner cases */ 88 int base = range > 2 ? 20 : 50; /* d2 and d3 are corner cases */
103 89
104 if (op->type == PLAYER)
105 {
106 int luck = op->stats.luck;
107
108 if (rndm (base) < min (10, abs (luck))) 90 if (rndm (base) < min (10, abs (op->stats.luck)))
109 {
110 //TODO: take luck into account
111 } 91 {
112 } 92 // we have a winner, increase/decrease number by one accordingly
93 int adjust = sign (op->stats.luck);
113 94
114 return rndm (r_min, r_max); 95 if (!prefer_high)
96 adjust = -adjust;
97
98 num = clamp (num + adjust, r_min, r_max);
99 }
100 }
101
102 return num;
115} 103}
116 104
117/* 105/*
118 * This is a 64 bit version of random_roll above. This is needed 106 * This is a 64 bit version of random_roll above. This is needed
119 * for exp loss calculations for players changing religions. 107 * for exp loss calculations for players changing religions.
120 */ 108 */
121sint64 109sint64
122random_roll64 (sint64 r_min, sint64 r_max, const object *op, int goodbad) 110random_roll64 (sint64 r_min, sint64 r_max, const object *op, bool prefer_high)
123{ 111{
124 sint64 omin = r_min; 112 if (r_min > r_max)
113 swap (r_min, r_max);
114
125 sint64 range = max (0, r_max - r_min + 1); 115 sint64 range = r_max - r_min + 1;
126 int base = range > 2 ? 20 : 50; /* d2 and d3 are corner cases */
127
128 /* 116 /*
129 * Make a call to get two 32 bit unsigned random numbers, and just to 117 * Make a call to get two 32 bit unsigned random numbers, and just do
130 * a little bitshifting. 118 * a little bitshifting.
131 */ 119 */
132 sint64 ran = (sint64) rndm.next () ^ ((sint64) rndm.next () << 31); 120 sint64 num = rndm.next () ^ (sint64 (rndm.next ()) << 31);
133 121
134 if (op->type != PLAYER) 122 num = num % range + r_min;
135 return ((ran % range) + r_min);
136 123
137 int luck = op->stats.luck; 124 if (op->stats.luck)
125 {
126 int base = range > 2 ? 20 : 50; /* d2 and d3 are corner cases */
138 127
139 if (rndm (base) < min (10, abs (luck))) 128 if (rndm (base) < min (10, abs (op->stats.luck)))
129 {
130 // we have a winner, increase/decrease number by one accordingly
131 int adjust = sign (op->stats.luck);
132
133 if (!prefer_high)
134 adjust = -adjust;
135
136 num = clamp (num + adjust, r_min, r_max);
137 }
140 { 138 }
141 /* we have a winner */
142 ((luck > 0) ? (luck = 1) : (luck = -1));
143 range -= luck;
144 if (range < 1)
145 return (omin); /*check again */
146 139
147 ((goodbad) ? (r_min += luck) : (range)); 140 return num;
148
149 return (max (omin, min (r_max, (ran % range) + r_min)));
150 }
151
152 return ran % range + r_min;
153} 141}
154 142
155/* 143/*
156 * Roll a number of dice (2d3, 4d6). Uses op to determine luck, 144 * Roll a number of dice (2d3, 4d6). Uses op to determine luck,
157 * If goodbad is non-zero, luck increases the roll, if zero, it decreases. 145 * If goodbad is non-zero, luck increases the roll, if zero, it decreases.
158 * Generally, op should be the player/caster/hitter requesting the roll, 146 * Generally, op should be the player/caster/hitter requesting the roll,
159 * not the recipient (ie, the poor slob getting hit). 147 * not the recipient (ie, the poor slob getting hit).
160 * The args are num D size (ie 4d6) [garbled 20010916] 148 * The args are num D size (ie 4d6) [garbled 20010916]
161 */ 149 */
162int 150int
163die_roll (int num, int size, const object *op, int goodbad) 151die_roll (int num, int size, const object *op, bool prefer_high)
164{ 152{
165 int min, luck, total, i, gotlucky; 153 int min_roll, luck, total, i, gotlucky;
166 154
167 int diff = size; 155 int diff = size;
168 min = 1; 156 min_roll = 1;
169 luck = total = gotlucky = 0; 157 luck = total = gotlucky = 0;
170 int base = diff > 2 ? 20 : 50; /* d2 and d3 are corner cases */ 158 int base = diff > 2 ? 20 : 50; /* d2 and d3 are corner cases */
171 159
172 if (size < 2 || diff < 1) 160 if (size < 2 || diff < 1)
173 { 161 {
174 LOG (llevError, "Calling die_roll with num=%d size=%d\n", num, size); 162 LOG (llevError | logBacktrace, "Calling die_roll with num=%d size=%d\n", num, size);
175 return num; /* avoids a float exception */ 163 return num; /* avoids a float exception */
176 } 164 }
177 165
178 if (op->type == PLAYER) 166 if (op->type == PLAYER)
179 luck = op->stats.luck; 167 luck = op->stats.luck;
180 168
181 for (i = 0; i < num; i++) 169 for (i = 0; i < num; i++)
182 { 170 {
183 if (rndm (base) < MIN (10, abs (luck)) && !gotlucky) 171 if (rndm (base) < min (10, abs (luck)) && !gotlucky)
184 { 172 {
185 /* we have a winner */ 173 /* we have a winner */
186 gotlucky++; 174 gotlucky++;
187 ((luck > 0) ? (luck = 1) : (luck = -1)); 175 ((luck > 0) ? (luck = 1) : (luck = -1));
188 diff -= luck; 176 diff -= luck;
189 if (diff < 1) 177 if (diff < 1)
190 return (num); /*check again */ 178 return (num); /*check again */
191 ((goodbad) ? (min += luck) : (diff)); 179 ((prefer_high) ? (min_roll += luck) : (diff));
192 total += MAX (1, MIN (size, rndm (diff) + min)); 180 total += max (1, min (size, rndm (diff) + min_roll));
193 } 181 }
194 else 182 else
195 total += rndm (size) + 1; 183 total += rndm (size) + 1;
196 } 184 }
197 185
314 path = path_combine (src, dst); 302 path = path_combine (src, dst);
315 path_normalize (path); 303 path_normalize (path);
316 return (path); 304 return (path);
317} 305}
318 306
319/**
320 * open_and_uncompress() first searches for the original filename. If it exist,
321 * then it opens it and returns the file-pointer.
322 */
323FILE *
324open_and_uncompress (const char *name, int flag, int *compressed)
325{
326 *compressed = 0;
327 return fopen (name, "r");
328}
329
330/*
331 * See open_and_uncompress().
332 */
333
334void
335close_and_delete (FILE * fp, int compressed)
336{
337 fclose (fp);
338}
339
340/*
341 * Strip out the media tags from a String.
342 * Warning the input string will contain the result string
343 */
344void
345strip_media_tag (char *message)
346{
347 int in_tag = 0;
348 char *dest;
349 char *src;
350
351 src = dest = message;
352 while (*src != '\0')
353 {
354 if (*src == '[')
355 {
356 in_tag = 1;
357 }
358 else if (in_tag && (*src == ']'))
359 in_tag = 0;
360 else if (!in_tag)
361 {
362 *dest = *src;
363 dest++;
364 }
365 src++;
366 }
367 *dest = '\0';
368}
369
370const char *
371strrstr (const char *haystack, const char *needle)
372{
373 const char *lastneedle;
374
375 lastneedle = NULL;
376 while ((haystack = strstr (haystack, needle)) != NULL)
377 {
378 lastneedle = haystack;
379 haystack++;
380 }
381 return lastneedle;
382
383}
384
385#define EOL_SIZE (sizeof("\n")-1) 307#define EOL_SIZE (sizeof("\n")-1)
386void 308void
387strip_endline (char *buf) 309strip_endline (char *buf)
388{ 310{
389 if (strlen (buf) < sizeof ("\n")) 311 if (*buf && buf [strlen (buf) - 1] == '\n')
390 {
391 return;
392 }
393 if (!strcmp (buf + strlen (buf) - EOL_SIZE, "\n"))
394 buf[strlen (buf) - EOL_SIZE] = '\0'; 312 buf [strlen (buf) - 1] = '\0';
395} 313}
396 314
397/** 315/**
398 * Replace in string src all occurrences of key by replacement. The resulting 316 * Replace in string src all occurrences of key by replacement. The resulting
399 * string is put into result; at most resultsize characters (including the 317 * string is put into result; at most resultsize characters (including the

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines