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.9 by root, Sun Sep 10 16:00:23 2006 UTC vs.
Revision 1.38 by root, Mon Jan 15 02:42:15 2007 UTC

1
2/*
3 * static char *rcsid_utils_c =
4 * "$Id: utils.C,v 1.9 2006/09/10 16:00:23 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 */
28
29#include <cstdlib>
30#include <sys/types.h>
31#include <unistd.h>
32#include <sys/time.h>
33#include <time.h>
34#include <signal.h>
33 35
34#include <global.h> 36#include <global.h>
35#include <funcpoint.h> 37#include <funcpoint.h>
36#include <material.h> 38#include <material.h>
37 39
103 diff = max - min + 1; 105 diff = max - min + 1;
104 ((diff > 2) ? (base = 20) : (base = 50)); /* d2 and d3 are corner cases */ 106 ((diff > 2) ? (base = 20) : (base = 50)); /* d2 and d3 are corner cases */
105 107
106 if (max < 1 || diff < 1) 108 if (max < 1 || diff < 1)
107 { 109 {
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); 110 LOG (llevError, "Calling random_roll with min=%" PRId64 " max=%" PRId64 "\n", min, max);
112#endif
113 return (min); /* avoids a float exception */ 111 return (min); /* avoids a float exception */
114 } 112 }
115 113
116 /* Don't know of a portable call to get 64 bit random values. 114 /* 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 115 * So make a call to get two 32 bit random numbers, and just to
203 return (min); 201 return (min);
204 202
205 return (RANDOM () % diff + min); 203 return (RANDOM () % diff + min);
206} 204}
207 205
208/* decay and destroy persihable items in a map */ 206/* decay and destroy perishable items in a map */
209
210void 207void
211decay_objects (mapstruct *m) 208maptile::decay_objects ()
212{ 209{
213 int x, y, destroy; 210 if (!spaces)
214 object *op, *otmp;
215
216 if (m->unique)
217 return; 211 return;
218 212
219 for (x = 0; x < MAP_WIDTH (m); x++) 213 for (mapspace *ms = spaces + size (); ms-- > spaces; )
220 for (y = 0; y < MAP_HEIGHT (m); y++) 214 for (object *above, *op = ms->bot; op; op = above)
221 for (op = get_map_ob (m, x, y); op; op = otmp)
222 { 215 {
216 above = op->above;
217
223 destroy = 0; 218 bool destroy = 0;
224 otmp = op->above; 219
220 // do not decay anything above unique floor tiles (yet :)
225 if (QUERY_FLAG (op, FLAG_IS_FLOOR) && QUERY_FLAG (op, FLAG_UNIQUE)) 221 if (QUERY_FLAG (op, FLAG_IS_FLOOR) && QUERY_FLAG (op, FLAG_UNIQUE))
226 break; 222 break;
223
227 if (QUERY_FLAG (op, FLAG_IS_FLOOR) || 224 if (QUERY_FLAG (op, FLAG_IS_FLOOR)
228 QUERY_FLAG (op, FLAG_OBJ_ORIGINAL) || 225 || QUERY_FLAG (op, FLAG_OBJ_ORIGINAL)
229 QUERY_FLAG (op, FLAG_OBJ_SAVE_ON_OVL) || 226 || 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)) 227 || QUERY_FLAG (op, FLAG_UNIQUE)
231 continue; 228 || QUERY_FLAG (op, FLAG_OVERLAY_FLOOR)
232 /* otherwise, we decay and destroy */ 229 || QUERY_FLAG (op, FLAG_UNPAID)
233 if (IS_WEAPON (op)) 230 || op->is_alive ())
231 ; // do not decay
232 else if (op->is_weapon ())
234 { 233 {
235 op->stats.dam--; 234 op->stats.dam--;
236 if (op->stats.dam < 0) 235 if (op->stats.dam < 0)
237 destroy = 1; 236 destroy = 1;
238 } 237 }
239 else if (IS_ARMOR (op)) 238 else if (op->is_armor ())
240 { 239 {
241 op->stats.ac--; 240 op->stats.ac--;
242 if (op->stats.ac < 0) 241 if (op->stats.ac < 0)
243 destroy = 1; 242 destroy = 1;
244 } 243 }
245 else if (op->type == FOOD) 244 else if (op->type == FOOD)
246 { 245 {
247 op->stats.food -= rndm (5, 20); 246 op->stats.food -= rndm (5, 20);
248 if (op->stats.food < 0) 247 if (op->stats.food < 0)
249 destroy = 1; 248 destroy = 1;
250 } 249 }
251 else 250 else
252 { 251 {
253 if (op->material & M_PAPER || op->material & M_LEATHER || 252 int mat = op->material;
254 op->material & M_WOOD || op->material & M_ORGANIC || op->material & M_CLOTH || op->material & M_LIQUID) 253
254 if (mat & M_PAPER
255 || mat & M_LEATHER
256 || mat & M_WOOD
257 || mat & M_ORGANIC
258 || mat & M_CLOTH
259 || mat & M_LIQUID
260 || (mat & M_IRON && rndm (1, 5) == 1)
261 || (mat & M_GLASS && rndm (1, 2) == 1)
262 || ((mat & M_STONE || mat & M_ADAMANT) && rndm (1, 10) == 1)
263 || ((mat & M_SOFT_METAL || mat & M_BONE) && rndm (1, 3) == 1)
264 || (mat & M_ICE && temp > 32))
255 destroy = 1; 265 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 } 266 }
267
267 /* adjust overall chance below */ 268 /* adjust overall chance below */
268 if (destroy && rndm (0, 1)) 269 if (destroy && rndm (0, 1))
269 { 270 op->destroy ();
270 remove_ob (op);
271 free_object (op);
272 }
273 } 271 }
274} 272}
275 273
276/* convert materialname to materialtype_t */ 274/* convert materialname to materialtype_t */
277 275
278materialtype_t * 276materialtype_t *
306 return; 304 return;
307 305
308 if (change->materialname != NULL && strcmp (op->materialname, change->materialname)) 306 if (change->materialname != NULL && strcmp (op->materialname, change->materialname))
309 return; 307 return;
310 308
311 if (!IS_ARMOR (op)) 309 if (!op->is_armor ())
312 return; 310 return;
313 311
314 mt = name_to_material (op->materialname); 312 mt = name_to_material (op->materialname);
315 if (!mt) 313 if (!mt)
316 { 314 {
362 { 360 {
363 if (op->material & mt->material && rndm (1, 100) <= mt->chance && 361 if (op->material & mt->material && rndm (1, 100) <= mt->chance &&
364 difficulty >= mt->difficulty && (op->magic >= mt->magic || mt->magic == 0)) 362 difficulty >= mt->difficulty && (op->magic >= mt->magic || mt->magic == 0))
365 { 363 {
366 lmt = mt; 364 lmt = mt;
367 if (!(IS_WEAPON (op) || IS_ARMOR (op))) 365 if (!(op->is_weapon () || op->is_armor ()))
368 break; 366 break;
369 } 367 }
370 } 368 }
371#endif 369#endif
372 } 370 }
380#ifndef NEW_MATERIAL_CODE 378#ifndef NEW_MATERIAL_CODE
381 op->materialname = lmt->name; 379 op->materialname = lmt->name;
382 return; 380 return;
383#else 381#else
384 382
385 if (op->stats.dam && IS_WEAPON (op)) 383 if (op->stats.dam && op->is_weapon ())
386 { 384 {
387 op->stats.dam += lmt->damage; 385 op->stats.dam += lmt->damage;
388 if (op->stats.dam < 1) 386 if (op->stats.dam < 1)
389 op->stats.dam = 1; 387 op->stats.dam = 1;
390 } 388 }
391 if (op->stats.sp && op->type == BOW) 389 if (op->stats.sp && op->type == BOW)
392 op->stats.sp += lmt->sp; 390 op->stats.sp += lmt->sp;
393 if (op->stats.wc && IS_WEAPON (op)) 391 if (op->stats.wc && op->is_weapon ())
394 op->stats.wc += lmt->wc; 392 op->stats.wc += lmt->wc;
395 if (IS_ARMOR (op)) 393 if (op->is_armor ())
396 { 394 {
397 if (op->stats.ac) 395 if (op->stats.ac)
398 op->stats.ac += lmt->ac; 396 op->stats.ac += lmt->ac;
399 for (j = 0; j < NROFATTACKS; j++) 397 for (j = 0; j < NROFATTACKS; j++)
400 if (op->resist[j] != 0) 398 if (op->resist[j] != 0)
406 op->resist[j] = -100; 404 op->resist[j] = -100;
407 } 405 }
408 } 406 }
409 op->materialname = add_string (lmt->name); 407 op->materialname = add_string (lmt->name);
410 /* dont make it unstackable if it doesn't need to be */ 408 /* dont make it unstackable if it doesn't need to be */
411 if (IS_WEAPON (op) || IS_ARMOR (op)) 409 if (op->is_weapon () || op->is_armor ())
412 { 410 {
413 op->weight = (op->weight * lmt->weight) / 100; 411 op->weight = (op->weight * lmt->weight) / 100;
414 op->value = (op->value * lmt->value) / 100; 412 op->value = (op->value * lmt->value) / 100;
415 } 413 }
416#endif 414#endif
531 529
532 strncpy (tmp, input, MAX_BUF - 5); 530 strncpy (tmp, input, MAX_BUF - 5);
533 /*trim all trailing commas, spaces etc. */ 531 /*trim all trailing commas, spaces etc. */
534 for (i = strlen (tmp); !isalnum (tmp[i]) && i >= 0; i--) 532 for (i = strlen (tmp); !isalnum (tmp[i]) && i >= 0; i--)
535 tmp[i] = '\0'; 533 tmp[i] = '\0';
534
536 strcat (tmp, "."); 535 strcat (tmp, ".");
537 536
538 p = strrchr (tmp, ','); 537 p = strrchr (tmp, ',');
539 if (p) 538 if (p)
540 { 539 {
544 strcat (input, " and"); 543 strcat (input, " and");
545 strcat (input, p); 544 strcat (input, p);
546 } 545 }
547 else 546 else
548 strcpy (input, tmp); 547 strcpy (input, tmp);
548
549 return; 549 return;
550} 550}
551 551
552/////////////////////////////////////////////////////////////////////////////
553
552void * 554void
553 zero_initialised::operator 555fork_abort (const char *msg)
554new (size_t s)
555{ 556{
556 //return calloc (1, s); 557 if (!fork ())
557 return g_slice_alloc0 (s); 558 {
558} 559 signal (SIGABRT, SIG_DFL);
560 abort ();
561 }
559 562
560void * 563 LOG (llevError, "fork abort: %s\n", msg);
561 zero_initialised::operator
562new[] (size_t s)
563{
564 //return calloc (1, s);
565 return g_slice_alloc0 (s);
566} 564}
567 565
568void 566void *salloc_ (int n) throw (std::bad_alloc)
569 zero_initialised::operator
570delete (void *p, size_t s)
571{ 567{
572 //free (p); return; 568 void *ptr = g_slice_alloc (n);
573 g_slice_free1 (s, p);
574}
575 569
576void 570 if (!ptr)
577 zero_initialised::operator 571 throw std::bad_alloc ();
578delete[] (void *p, size_t s) 572
579{ 573 return ptr;
580 //free (p); return;
581 g_slice_free1 (s, p);
582} 574}
575
576void *salloc_ (int n, void *src) throw (std::bad_alloc)
577{
578 void *ptr = salloc_ (n);
579
580 if (src)
581 memcpy (ptr, src, n);
582 else
583 memset (ptr, 0, n);
584
585 return ptr;
586}
587
588void assign (char *dst, const char *src, int maxlen)
589{
590 if (!src)
591 src = "";
592
593 int len = strlen (src);
594
595 if (len >= maxlen - 1)
596 {
597 if (maxlen <= 4)
598 {
599 memset (dst, '.', maxlen - 1);
600 dst [maxlen - 1] = 0;
601 }
602 else
603 {
604 memcpy (dst, src, maxlen - 4);
605 memcpy (dst + maxlen - 4, "...", 4);
606 }
607 }
608 else
609 memcpy (dst, src, len + 1);
610}
611
612tstamp now ()
613{
614 struct timeval tv;
615
616 gettimeofday (&tv, 0);
617 return tstamp (tv.tv_sec) + tstamp (tv.tv_usec) * tstamp (1e-6);
618}
619
620int
621similar_direction (int a, int b)
622{
623 if (!a || !b)
624 return 0;
625
626 int diff = (b - a) & 7;
627 return diff <= 1 || diff >= 7;
628}
629

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines