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.35 by root, Mon Jan 1 13:31:46 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
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 if (!spaces)
214 object *op, *otmp;
215
216 if (m->unique)
217 return; 205 return;
218 206
219 for (x = 0; x < MAP_WIDTH (m); x++) 207 for (mapspace *ms = spaces + size (); ms-- > spaces; )
220 for (y = 0; y < MAP_HEIGHT (m); y++) 208 for (object *above, *op = ms->bot; op; op = above)
221 for (op = get_map_ob (m, x, y); op; op = otmp)
222 { 209 {
210 above = op->above;
211
223 destroy = 0; 212 bool destroy = 0;
224 otmp = op->above; 213
214 // do not decay anything above unique floor tiles (yet :)
225 if (QUERY_FLAG (op, FLAG_IS_FLOOR) && QUERY_FLAG (op, FLAG_UNIQUE)) 215 if (QUERY_FLAG (op, FLAG_IS_FLOOR) && QUERY_FLAG (op, FLAG_UNIQUE))
226 break; 216 break;
217
227 if (QUERY_FLAG (op, FLAG_IS_FLOOR) || 218 if (QUERY_FLAG (op, FLAG_IS_FLOOR)
228 QUERY_FLAG (op, FLAG_OBJ_ORIGINAL) || 219 || QUERY_FLAG (op, FLAG_OBJ_ORIGINAL)
229 QUERY_FLAG (op, FLAG_OBJ_SAVE_ON_OVL) || 220 || 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)) 221 || QUERY_FLAG (op, FLAG_UNIQUE)
231 continue; 222 || QUERY_FLAG (op, FLAG_OVERLAY_FLOOR)
232 /* otherwise, we decay and destroy */ 223 || QUERY_FLAG (op, FLAG_UNPAID)
233 if (IS_WEAPON (op)) 224 || op->is_alive ())
225 ; // do not decay
226 else if (op->is_weapon ())
234 { 227 {
235 op->stats.dam--; 228 op->stats.dam--;
236 if (op->stats.dam < 0) 229 if (op->stats.dam < 0)
237 destroy = 1; 230 destroy = 1;
238 } 231 }
239 else if (IS_ARMOR (op)) 232 else if (op->is_armor ())
240 { 233 {
241 op->stats.ac--; 234 op->stats.ac--;
242 if (op->stats.ac < 0) 235 if (op->stats.ac < 0)
243 destroy = 1; 236 destroy = 1;
244 } 237 }
245 else if (op->type == FOOD) 238 else if (op->type == FOOD)
246 { 239 {
247 op->stats.food -= rndm (5, 20); 240 op->stats.food -= rndm (5, 20);
248 if (op->stats.food < 0) 241 if (op->stats.food < 0)
249 destroy = 1; 242 destroy = 1;
250 } 243 }
251 else 244 else
252 { 245 {
253 if (op->material & M_PAPER || op->material & M_LEATHER || 246 int mat = op->material;
254 op->material & M_WOOD || op->material & M_ORGANIC || op->material & M_CLOTH || op->material & M_LIQUID) 247
248 if (mat & M_PAPER
249 || mat & M_LEATHER
250 || mat & M_WOOD
251 || mat & M_ORGANIC
252 || mat & M_CLOTH
253 || mat & M_LIQUID
254 || (mat & M_IRON && rndm (1, 5) == 1)
255 || (mat & M_GLASS && rndm (1, 2) == 1)
256 || ((mat & M_STONE || mat & M_ADAMANT) && rndm (1, 10) == 1)
257 || ((mat & M_SOFT_METAL || mat & M_BONE) && rndm (1, 3) == 1)
258 || (mat & M_ICE && temp > 32))
255 destroy = 1; 259 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 } 260 }
261
267 /* adjust overall chance below */ 262 /* adjust overall chance below */
268 if (destroy && rndm (0, 1)) 263 if (destroy && rndm (0, 1))
269 { 264 op->destroy ();
270 remove_ob (op);
271 free_object (op);
272 }
273 } 265 }
274} 266}
275 267
276/* convert materialname to materialtype_t */ 268/* convert materialname to materialtype_t */
277 269
278materialtype_t * 270materialtype_t *
306 return; 298 return;
307 299
308 if (change->materialname != NULL && strcmp (op->materialname, change->materialname)) 300 if (change->materialname != NULL && strcmp (op->materialname, change->materialname))
309 return; 301 return;
310 302
311 if (!IS_ARMOR (op)) 303 if (!op->is_armor ())
312 return; 304 return;
313 305
314 mt = name_to_material (op->materialname); 306 mt = name_to_material (op->materialname);
315 if (!mt) 307 if (!mt)
316 { 308 {
362 { 354 {
363 if (op->material & mt->material && rndm (1, 100) <= mt->chance && 355 if (op->material & mt->material && rndm (1, 100) <= mt->chance &&
364 difficulty >= mt->difficulty && (op->magic >= mt->magic || mt->magic == 0)) 356 difficulty >= mt->difficulty && (op->magic >= mt->magic || mt->magic == 0))
365 { 357 {
366 lmt = mt; 358 lmt = mt;
367 if (!(IS_WEAPON (op) || IS_ARMOR (op))) 359 if (!(op->is_weapon () || op->is_armor ()))
368 break; 360 break;
369 } 361 }
370 } 362 }
371#endif 363#endif
372 } 364 }
380#ifndef NEW_MATERIAL_CODE 372#ifndef NEW_MATERIAL_CODE
381 op->materialname = lmt->name; 373 op->materialname = lmt->name;
382 return; 374 return;
383#else 375#else
384 376
385 if (op->stats.dam && IS_WEAPON (op)) 377 if (op->stats.dam && op->is_weapon ())
386 { 378 {
387 op->stats.dam += lmt->damage; 379 op->stats.dam += lmt->damage;
388 if (op->stats.dam < 1) 380 if (op->stats.dam < 1)
389 op->stats.dam = 1; 381 op->stats.dam = 1;
390 } 382 }
391 if (op->stats.sp && op->type == BOW) 383 if (op->stats.sp && op->type == BOW)
392 op->stats.sp += lmt->sp; 384 op->stats.sp += lmt->sp;
393 if (op->stats.wc && IS_WEAPON (op)) 385 if (op->stats.wc && op->is_weapon ())
394 op->stats.wc += lmt->wc; 386 op->stats.wc += lmt->wc;
395 if (IS_ARMOR (op)) 387 if (op->is_armor ())
396 { 388 {
397 if (op->stats.ac) 389 if (op->stats.ac)
398 op->stats.ac += lmt->ac; 390 op->stats.ac += lmt->ac;
399 for (j = 0; j < NROFATTACKS; j++) 391 for (j = 0; j < NROFATTACKS; j++)
400 if (op->resist[j] != 0) 392 if (op->resist[j] != 0)
406 op->resist[j] = -100; 398 op->resist[j] = -100;
407 } 399 }
408 } 400 }
409 op->materialname = add_string (lmt->name); 401 op->materialname = add_string (lmt->name);
410 /* dont make it unstackable if it doesn't need to be */ 402 /* dont make it unstackable if it doesn't need to be */
411 if (IS_WEAPON (op) || IS_ARMOR (op)) 403 if (op->is_weapon () || op->is_armor ())
412 { 404 {
413 op->weight = (op->weight * lmt->weight) / 100; 405 op->weight = (op->weight * lmt->weight) / 100;
414 op->value = (op->value * lmt->value) / 100; 406 op->value = (op->value * lmt->value) / 100;
415 } 407 }
416#endif 408#endif
531 523
532 strncpy (tmp, input, MAX_BUF - 5); 524 strncpy (tmp, input, MAX_BUF - 5);
533 /*trim all trailing commas, spaces etc. */ 525 /*trim all trailing commas, spaces etc. */
534 for (i = strlen (tmp); !isalnum (tmp[i]) && i >= 0; i--) 526 for (i = strlen (tmp); !isalnum (tmp[i]) && i >= 0; i--)
535 tmp[i] = '\0'; 527 tmp[i] = '\0';
528
536 strcat (tmp, "."); 529 strcat (tmp, ".");
537 530
538 p = strrchr (tmp, ','); 531 p = strrchr (tmp, ',');
539 if (p) 532 if (p)
540 { 533 {
544 strcat (input, " and"); 537 strcat (input, " and");
545 strcat (input, p); 538 strcat (input, p);
546 } 539 }
547 else 540 else
548 strcpy (input, tmp); 541 strcpy (input, tmp);
542
549 return; 543 return;
550} 544}
551 545
552void * 546/////////////////////////////////////////////////////////////////////////////
553 zero_initialised::operator
554new (size_t s)
555{
556 //return calloc (1, s);
557 return g_slice_alloc0 (s);
558}
559 547
560void * 548void *salloc_ (int n) throw (std::bad_alloc)
561 zero_initialised::operator
562new[] (size_t s)
563{ 549{
564 //return calloc (1, s); 550 void *ptr = g_slice_alloc (n);
565 return g_slice_alloc0 (s);
566}
567 551
568void 552 if (!ptr)
569 zero_initialised::operator 553 throw std::bad_alloc ();
570delete (void *p, size_t s)
571{
572 //free (p); return;
573 g_slice_free1 (s, p);
574}
575 554
576void 555 return ptr;
577 zero_initialised::operator
578delete[] (void *p, size_t s)
579{
580 //free (p); return;
581 g_slice_free1 (s, p);
582} 556}
557
558void *salloc_ (int n, void *src) throw (std::bad_alloc)
559{
560 void *ptr = salloc_ (n);
561
562 if (src)
563 memcpy (ptr, src, n);
564 else
565 memset (ptr, 0, n);
566
567 return ptr;
568}
569
570void assign (char *dst, const char *src, int maxlen)
571{
572 if (!src)
573 src = "";
574
575 int len = strlen (src);
576
577 if (len >= maxlen - 1)
578 {
579 if (maxlen <= 4)
580 {
581 memset (dst, '.', maxlen - 1);
582 dst [maxlen - 1] = 0;
583 }
584 else
585 {
586 memcpy (dst, src, maxlen - 4);
587 memcpy (dst + maxlen - 4, "...", 4);
588 }
589 }
590 else
591 memcpy (dst, src, len + 1);
592}
593
594tstamp now ()
595{
596 struct timeval tv;
597
598 gettimeofday (&tv, 0);
599 return tstamp (tv.tv_sec) + tstamp (tv.tv_usec) * tstamp (1e-6);
600}
601
602int
603similar_direction (int a, int b)
604{
605 if (!a || !b)
606 return 0;
607
608 int diff = (b - a) & 7;
609 return diff <= 1 || diff >= 7;
610}
611

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines