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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines