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

Comparing deliantra/server/common/utils.C (file contents):
Revision 1.10 by root, Mon Sep 11 01:16:20 2006 UTC vs.
Revision 1.34 by root, Mon Jan 1 12:28:46 2007 UTC

1
2/*
3 * static char *rcsid_utils_c =
4 * "$Id: utils.C,v 1.10 2006/09/11 01:16:20 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 The authors can be reached via e-mail at crossfire-devel@real-time.com 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
28*/ 22*/
29 23
30/* 24/*
31 * General convenience functions for crossfire. 25 * General convenience functions for crossfire.
32 */ 26 */
33 27
34#include <global.h> 28#include <global.h>
35#include <funcpoint.h> 29#include <funcpoint.h>
36#include <material.h> 30#include <material.h>
37 31
32#include <sys/time.h>
33#include <time.h>
38#include <glib.h> 34#include <glib.h>
39 35
40/* 36/*
41 * The random functions here take luck into account when rolling random 37 * The random functions here take luck into account when rolling random
42 * dice or numbers. This function has less of an impact the larger the 38 * dice or numbers. This function has less of an impact the larger the
103 diff = max - min + 1; 99 diff = max - min + 1;
104 ((diff > 2) ? (base = 20) : (base = 50)); /* d2 and d3 are corner cases */ 100 ((diff > 2) ? (base = 20) : (base = 50)); /* d2 and d3 are corner cases */
105 101
106 if (max < 1 || diff < 1) 102 if (max < 1 || diff < 1)
107 { 103 {
108#ifndef WIN32
109 LOG (llevError, "Calling random_roll with min=%lld max=%lld\n", min, max);
110#else
111 LOG (llevError, "Calling random_roll with min=%I64d max=%I64d\n", min, max); 104 LOG (llevError, "Calling random_roll with min=%" PRId64 " max=%" PRId64 "\n", min, max);
112#endif
113 return (min); /* avoids a float exception */ 105 return (min); /* avoids a float exception */
114 } 106 }
115 107
116 /* Don't know of a portable call to get 64 bit random values. 108 /* Don't know of a portable call to get 64 bit random values.
117 * So make a call to get two 32 bit random numbers, and just to 109 * So make a call to get two 32 bit random numbers, and just to
203 return (min); 195 return (min);
204 196
205 return (RANDOM () % diff + min); 197 return (RANDOM () % diff + min);
206} 198}
207 199
208/* decay and destroy persihable items in a map */ 200/* decay and destroy perishable items in a map */
209
210void 201void
211decay_objects (mapstruct *m) 202maptile::decay_objects ()
212{ 203{
213 int x, y, destroy; 204 for (int x = 0; x < width; x++)
214 object *op, *otmp; 205 for (int y = 0; y < height; y++)
215 206 for (object *above = 0, *op = at (x, y).bot; op; op = above)
216 if (m->unique)
217 return;
218
219 for (x = 0; x < MAP_WIDTH (m); x++)
220 for (y = 0; y < MAP_HEIGHT (m); y++)
221 for (op = get_map_ob (m, x, y); op; op = otmp)
222 { 207 {
223 destroy = 0; 208 bool destroy = 0;
209
224 otmp = op->above; 210 above = op->above;
211
212 // do not decay anything above unique floor tiles (yet :)
225 if (QUERY_FLAG (op, FLAG_IS_FLOOR) && QUERY_FLAG (op, FLAG_UNIQUE)) 213 if (QUERY_FLAG (op, FLAG_IS_FLOOR) && QUERY_FLAG (op, FLAG_UNIQUE))
226 break; 214 break;
215
227 if (QUERY_FLAG (op, FLAG_IS_FLOOR) || 216 if (QUERY_FLAG (op, FLAG_IS_FLOOR)
228 QUERY_FLAG (op, FLAG_OBJ_ORIGINAL) || 217 || QUERY_FLAG (op, FLAG_OBJ_ORIGINAL)
229 QUERY_FLAG (op, FLAG_OBJ_SAVE_ON_OVL) || 218 || QUERY_FLAG (op, FLAG_OBJ_SAVE_ON_OVL)
230 QUERY_FLAG (op, FLAG_UNIQUE) || QUERY_FLAG (op, FLAG_OVERLAY_FLOOR) || QUERY_FLAG (op, FLAG_UNPAID) || IS_LIVE (op)) 219 || QUERY_FLAG (op, FLAG_UNIQUE)
231 continue; 220 || QUERY_FLAG (op, FLAG_OVERLAY_FLOOR)
232 /* otherwise, we decay and destroy */ 221 || QUERY_FLAG (op, FLAG_UNPAID)
233 if (IS_WEAPON (op)) 222 || op->is_alive ())
223 ; // do not decay
224 else if (op->is_weapon ())
234 { 225 {
235 op->stats.dam--; 226 op->stats.dam--;
236 if (op->stats.dam < 0) 227 if (op->stats.dam < 0)
237 destroy = 1; 228 destroy = 1;
238 } 229 }
239 else if (IS_ARMOR (op)) 230 else if (op->is_armor ())
240 { 231 {
241 op->stats.ac--; 232 op->stats.ac--;
242 if (op->stats.ac < 0) 233 if (op->stats.ac < 0)
243 destroy = 1; 234 destroy = 1;
244 } 235 }
248 if (op->stats.food < 0) 239 if (op->stats.food < 0)
249 destroy = 1; 240 destroy = 1;
250 } 241 }
251 else 242 else
252 { 243 {
253 if (op->material & M_PAPER || op->material & M_LEATHER || 244 int mat = op->material;
254 op->material & M_WOOD || op->material & M_ORGANIC || op->material & M_CLOTH || op->material & M_LIQUID) 245
255 destroy = 1; 246 if (mat & M_PAPER
247 || mat & M_LEATHER
248 || mat & M_WOOD
249 || mat & M_ORGANIC
250 || mat & M_CLOTH
251 || mat & M_LIQUID
256 if (op->material & M_IRON && rndm (1, 5) == 1) 252 || (mat & M_IRON && rndm (1, 5) == 1)
257 destroy = 1;
258 if (op->material & M_GLASS && rndm (1, 2) == 1) 253 || (mat & M_GLASS && rndm (1, 2) == 1)
259 destroy = 1;
260 if ((op->material & M_STONE || op->material & M_ADAMANT) && rndm (1, 10) == 1) 254 || ((mat & M_STONE || mat & M_ADAMANT) && rndm (1, 10) == 1)
261 destroy = 1;
262 if ((op->material & M_SOFT_METAL || op->material & M_BONE) && rndm (1, 3) == 1) 255 || ((mat & M_SOFT_METAL || mat & M_BONE) && rndm (1, 3) == 1)
263 destroy = 1; 256 || (mat & M_ICE && temp > 32))
264 if (op->material & M_ICE && MAP_TEMP (m) > 32)
265 destroy = 1; 257 destroy = 1;
266 } 258 }
259
267 /* adjust overall chance below */ 260 /* adjust overall chance below */
268 if (destroy && rndm (0, 1)) 261 if (destroy && rndm (0, 1))
269 { 262 op->destroy ();
270 remove_ob (op);
271 free_object (op);
272 }
273 } 263 }
274} 264}
275 265
276/* convert materialname to materialtype_t */ 266/* convert materialname to materialtype_t */
277 267
306 return; 296 return;
307 297
308 if (change->materialname != NULL && strcmp (op->materialname, change->materialname)) 298 if (change->materialname != NULL && strcmp (op->materialname, change->materialname))
309 return; 299 return;
310 300
311 if (!IS_ARMOR (op)) 301 if (!op->is_armor ())
312 return; 302 return;
313 303
314 mt = name_to_material (op->materialname); 304 mt = name_to_material (op->materialname);
315 if (!mt) 305 if (!mt)
316 { 306 {
362 { 352 {
363 if (op->material & mt->material && rndm (1, 100) <= mt->chance && 353 if (op->material & mt->material && rndm (1, 100) <= mt->chance &&
364 difficulty >= mt->difficulty && (op->magic >= mt->magic || mt->magic == 0)) 354 difficulty >= mt->difficulty && (op->magic >= mt->magic || mt->magic == 0))
365 { 355 {
366 lmt = mt; 356 lmt = mt;
367 if (!(IS_WEAPON (op) || IS_ARMOR (op))) 357 if (!(op->is_weapon () || op->is_armor ()))
368 break; 358 break;
369 } 359 }
370 } 360 }
371#endif 361#endif
372 } 362 }
380#ifndef NEW_MATERIAL_CODE 370#ifndef NEW_MATERIAL_CODE
381 op->materialname = lmt->name; 371 op->materialname = lmt->name;
382 return; 372 return;
383#else 373#else
384 374
385 if (op->stats.dam && IS_WEAPON (op)) 375 if (op->stats.dam && op->is_weapon ())
386 { 376 {
387 op->stats.dam += lmt->damage; 377 op->stats.dam += lmt->damage;
388 if (op->stats.dam < 1) 378 if (op->stats.dam < 1)
389 op->stats.dam = 1; 379 op->stats.dam = 1;
390 } 380 }
391 if (op->stats.sp && op->type == BOW) 381 if (op->stats.sp && op->type == BOW)
392 op->stats.sp += lmt->sp; 382 op->stats.sp += lmt->sp;
393 if (op->stats.wc && IS_WEAPON (op)) 383 if (op->stats.wc && op->is_weapon ())
394 op->stats.wc += lmt->wc; 384 op->stats.wc += lmt->wc;
395 if (IS_ARMOR (op)) 385 if (op->is_armor ())
396 { 386 {
397 if (op->stats.ac) 387 if (op->stats.ac)
398 op->stats.ac += lmt->ac; 388 op->stats.ac += lmt->ac;
399 for (j = 0; j < NROFATTACKS; j++) 389 for (j = 0; j < NROFATTACKS; j++)
400 if (op->resist[j] != 0) 390 if (op->resist[j] != 0)
406 op->resist[j] = -100; 396 op->resist[j] = -100;
407 } 397 }
408 } 398 }
409 op->materialname = add_string (lmt->name); 399 op->materialname = add_string (lmt->name);
410 /* dont make it unstackable if it doesn't need to be */ 400 /* dont make it unstackable if it doesn't need to be */
411 if (IS_WEAPON (op) || IS_ARMOR (op)) 401 if (op->is_weapon () || op->is_armor ())
412 { 402 {
413 op->weight = (op->weight * lmt->weight) / 100; 403 op->weight = (op->weight * lmt->weight) / 100;
414 op->value = (op->value * lmt->value) / 100; 404 op->value = (op->value * lmt->value) / 100;
415 } 405 }
416#endif 406#endif
531 521
532 strncpy (tmp, input, MAX_BUF - 5); 522 strncpy (tmp, input, MAX_BUF - 5);
533 /*trim all trailing commas, spaces etc. */ 523 /*trim all trailing commas, spaces etc. */
534 for (i = strlen (tmp); !isalnum (tmp[i]) && i >= 0; i--) 524 for (i = strlen (tmp); !isalnum (tmp[i]) && i >= 0; i--)
535 tmp[i] = '\0'; 525 tmp[i] = '\0';
526
536 strcat (tmp, "."); 527 strcat (tmp, ".");
537 528
538 p = strrchr (tmp, ','); 529 p = strrchr (tmp, ',');
539 if (p) 530 if (p)
540 { 531 {
544 strcat (input, " and"); 535 strcat (input, " and");
545 strcat (input, p); 536 strcat (input, p);
546 } 537 }
547 else 538 else
548 strcpy (input, tmp); 539 strcpy (input, tmp);
540
549 return; 541 return;
550} 542}
551 543
552void * 544/////////////////////////////////////////////////////////////////////////////
553zero_initialised::operator new (size_t s, void *p) 545
546void *salloc_ (int n) throw (std::bad_alloc)
554{ 547{
555 memset (p, 0, s); 548 void *ptr = g_slice_alloc (n);
549
550 if (!ptr)
551 throw std::bad_alloc ();
552
556 return p; 553 return ptr;
557} 554}
558 555
559void * 556void *salloc_ (int n, void *src) throw (std::bad_alloc)
560zero_initialised::operator new (size_t s)
561{ 557{
562 //return calloc (1, s); 558 void *ptr = salloc_ (n);
563 return g_slice_alloc0 (s);
564}
565 559
566void * 560 if (src)
567 zero_initialised::operator new[] (size_t s) 561 memcpy (ptr, src, n);
568{ 562 else
569 //return calloc (1, s); 563 memset (ptr, 0, n);
570 return g_slice_alloc0 (s);
571}
572 564
573void 565 return ptr;
574zero_initialised::operator delete (void *p, size_t s)
575{
576 //free (p); return;
577 g_slice_free1 (s, p);
578} 566}
579 567
580void 568void assign (char *dst, const char *src, int maxlen)
581zero_initialised::operator delete[] (void *p, size_t s)
582{ 569{
583 //free (p); return; 570 if (!src)
584 g_slice_free1 (s, p); 571 src = "";
572
573 int len = strlen (src);
574
575 if (len >= maxlen - 1)
576 {
577 if (maxlen <= 4)
578 {
579 memset (dst, '.', maxlen - 1);
580 dst [maxlen - 1] = 0;
581 }
582 else
583 {
584 memcpy (dst, src, maxlen - 4);
585 memcpy (dst + maxlen - 4, "...", 4);
586 }
587 }
588 else
589 memcpy (dst, src, len + 1);
585} 590}
591
592tstamp now ()
593{
594 struct timeval tv;
595
596 gettimeofday (&tv, 0);
597 return tstamp (tv.tv_sec) + tstamp (tv.tv_usec) * tstamp (1e-6);
598}
599
600int
601similar_direction (int a, int b)
602{
603 if (!a || !b)
604 return 0;
605
606 int diff = (b - a) & 7;
607 return diff <= 1 || diff >= 7;
608}
609

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines