… | |
… | |
210 | attachable::destroy () |
210 | attachable::destroy () |
211 | { |
211 | { |
212 | if (destroyed ()) |
212 | if (destroyed ()) |
213 | return; |
213 | return; |
214 | |
214 | |
215 | flags |= F_DESTROYED; |
215 | attachable_flags |= F_DESTROYED; |
216 | do_destroy (); |
216 | do_destroy (); |
217 | sever_self (); |
217 | sever_self (); |
218 | } |
218 | } |
219 | |
219 | |
220 | void |
220 | void |
… | |
… | |
402 | hv_clear ((HV *)sv); |
402 | hv_clear ((HV *)sv); |
403 | sv_unmagic (sv, PERL_MAGIC_ext); |
403 | sv_unmagic (sv, PERL_MAGIC_ext); |
404 | } |
404 | } |
405 | #endif |
405 | #endif |
406 | |
406 | |
|
|
407 | static long SvPTR_nc (SV *sv) |
|
|
408 | { |
|
|
409 | sv = SvRV (sv); |
|
|
410 | |
|
|
411 | // very important shortcut |
|
|
412 | if (expect_true (SvMAGIC (sv) && SvMAGIC (sv)->mg_type == PERL_MAGIC_ext)) |
|
|
413 | return (long)SvMAGIC (sv)->mg_ptr; |
|
|
414 | |
|
|
415 | if (MAGIC *mg = mg_find (sv, PERL_MAGIC_ext)) |
|
|
416 | return (long)mg->mg_ptr; |
|
|
417 | |
|
|
418 | croak ("perl code used object, but C object is already destroyed, caught"); |
|
|
419 | } |
|
|
420 | |
407 | static long |
421 | static long |
408 | SvPTR (SV *sv, const char *klass) |
422 | SvPTR (SV *sv, const char *klass) |
409 | { |
423 | { |
410 | if (!sv_derived_from (sv, klass)) |
424 | if (!sv_derived_from (sv, klass)) |
411 | croak ("object of type %s expected", klass); |
425 | croak ("object of type %s expected", klass); |
412 | |
426 | |
413 | MAGIC *mg = mg_find (SvRV (sv), PERL_MAGIC_ext); |
427 | return SvPTR_nc (sv); |
414 | |
|
|
415 | if (!mg) |
|
|
416 | croak ("perl code used %s object, but C object is already destroyed, caught", klass); |
|
|
417 | |
|
|
418 | return (long)mg->mg_ptr; |
|
|
419 | } |
428 | } |
420 | |
429 | |
421 | static long noinline |
430 | static long noinline |
422 | SvPTR_ornull (SV *sv, const char *klass) |
431 | SvPTR_ornull (SV *sv, const char *klass) |
423 | { |
432 | { |
424 | if (SvOK (sv)) |
433 | if (expect_false (!SvOK (sv))) return 0; |
|
|
434 | |
425 | return SvPTR (sv, klass); |
435 | return SvPTR (sv, klass); |
426 | else |
436 | } |
427 | return 0; |
437 | |
|
|
438 | static long noinline |
|
|
439 | SvPTR_ornull_client (SV *sv) |
|
|
440 | { |
|
|
441 | if (expect_false (!SvOK (sv))) return 0; |
|
|
442 | |
|
|
443 | if (!SvROK (sv) |
|
|
444 | || (SvSTASH (SvRV (sv)) != stash_cf_client_wrap |
|
|
445 | && !sv_derived_from (sv, "cf::client"))) |
|
|
446 | croak ("object of type cf::client expected"); |
|
|
447 | |
|
|
448 | return SvPTR_nc (sv); |
|
|
449 | } |
|
|
450 | |
|
|
451 | static long noinline |
|
|
452 | SvPTR_ornull_object (SV *sv) |
|
|
453 | { |
|
|
454 | if (expect_false (!SvOK (sv))) return 0; |
|
|
455 | |
|
|
456 | if (!SvROK (sv) |
|
|
457 | || (SvSTASH (SvRV (sv)) != stash_cf_object_wrap |
|
|
458 | && SvSTASH (SvRV (sv)) != stash_cf_object_player_wrap |
|
|
459 | && SvSTASH (SvRV (sv)) != stash_cf_arch_wrap |
|
|
460 | && !sv_derived_from (sv, "cf::object"))) |
|
|
461 | croak ("object of type cf::object expected"); |
|
|
462 | |
|
|
463 | return SvPTR_nc (sv); |
|
|
464 | } |
|
|
465 | |
|
|
466 | static long noinline |
|
|
467 | SvPTR_ornull_player (SV *sv) |
|
|
468 | { |
|
|
469 | if (expect_false (!SvOK (sv))) return 0; |
|
|
470 | |
|
|
471 | if (!SvROK (sv) |
|
|
472 | || (SvSTASH (SvRV (sv)) != stash_cf_player_wrap |
|
|
473 | && !sv_derived_from (sv, "cf::player"))) |
|
|
474 | croak ("object of type cf::player expected"); |
|
|
475 | |
|
|
476 | return SvPTR_nc (sv); |
428 | } |
477 | } |
429 | |
478 | |
430 | static inline SV *to_sv (const shstr & v) { return newSVpvn_utf8 ((const char *)v, v.length (), 1); } |
479 | static inline SV *to_sv (const shstr & v) { return newSVpvn_utf8 ((const char *)v, v.length (), 1); } |
431 | static inline SV *to_sv (const char * v) { return v ? newSVpv (v, 0) : newSV (0); } |
480 | static inline SV *to_sv (const char * v) { return v ? newSVpv (v, 0) : newSV (0); } |
432 | static inline SV *to_sv (bool v) { return newSViv (v); } |
481 | static inline SV *to_sv (bool v) { return newSViv (v); } |
… | |
… | |
494 | static inline void sv_to (SV *sv, unsigned long &v) { v = SvUV (sv); } |
543 | static inline void sv_to (SV *sv, unsigned long &v) { v = SvUV (sv); } |
495 | static inline void sv_to (SV *sv, signed long long &v) { v = ( signed long long)SvVAL64 (sv); } |
544 | static inline void sv_to (SV *sv, signed long long &v) { v = ( signed long long)SvVAL64 (sv); } |
496 | static inline void sv_to (SV *sv, unsigned long long &v) { v = (unsigned long long)SvVAL64 (sv); } |
545 | static inline void sv_to (SV *sv, unsigned long long &v) { v = (unsigned long long)SvVAL64 (sv); } |
497 | static inline void sv_to (SV *sv, float &v) { v = SvNV (sv); } |
546 | static inline void sv_to (SV *sv, float &v) { v = SvNV (sv); } |
498 | static inline void sv_to (SV *sv, double &v) { v = SvNV (sv); } |
547 | static inline void sv_to (SV *sv, double &v) { v = SvNV (sv); } |
499 | static inline void sv_to (SV *sv, client * &v) { v = (client *)(attachable *)SvPTR_ornull (sv, "cf::client"); } |
548 | static inline void sv_to (SV *sv, client * &v) { v = (client *) (attachable *)SvPTR_ornull_client (sv); } |
500 | static inline void sv_to (SV *sv, player * &v) { v = (player *)(attachable *)SvPTR_ornull (sv, "cf::player"); } |
549 | static inline void sv_to (SV *sv, player * &v) { v = (player *) (attachable *)SvPTR_ornull_player (sv); } |
501 | static inline void sv_to (SV *sv, object * &v) { v = (object *)(attachable *)SvPTR_ornull (sv, "cf::object"); } |
550 | static inline void sv_to (SV *sv, object * &v) { v = (object *) (attachable *)SvPTR_ornull_object (sv); } |
502 | static inline void sv_to (SV *sv, archetype * &v) { v = (archetype *)(attachable *)SvPTR_ornull (sv, "cf::arch"); } |
551 | static inline void sv_to (SV *sv, archetype * &v) { v = (archetype *)(attachable *)SvPTR_ornull (sv, "cf::arch"); } |
503 | static inline void sv_to (SV *sv, maptile * &v) { v = (maptile *)(attachable *)SvPTR_ornull (sv, "cf::map"); } |
552 | static inline void sv_to (SV *sv, maptile * &v) { v = (maptile *) (attachable *)SvPTR_ornull (sv, "cf::map"); } |
504 | static inline void sv_to (SV *sv, region * &v) { v = (region *)(attachable *)SvPTR_ornull (sv, "cf::region"); } |
553 | static inline void sv_to (SV *sv, region * &v) { v = (region *) (attachable *)SvPTR_ornull (sv, "cf::region"); } |
505 | static inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); } |
554 | static inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); } |
506 | static inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); } |
555 | static inline void sv_to (SV *sv, partylist * &v) { v = (partylist *) SvPTR_ornull (sv, "cf::party"); } |
507 | static inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); } |
556 | static inline void sv_to (SV *sv, living * &v) { v = (living *) SvPTR_ornull (sv, "cf::living"); } |
508 | static inline void sv_to (SV *sv, mapspace * &v) { v = (mapspace *)SvPTR_ornull (sv, "cf::mapspace"); } |
557 | static inline void sv_to (SV *sv, mapspace * &v) { v = (mapspace *) SvPTR_ornull (sv, "cf::mapspace"); } |
509 | static inline void sv_to (SV *sv, object_freezer * &v) { v = (object_freezer *)SvPTR_ornull (sv, "cf::object::freezer"); } |
558 | static inline void sv_to (SV *sv, object_freezer * &v) { v = (object_freezer *) SvPTR_ornull (sv, "cf::object::freezer"); } |
510 | static inline void sv_to (SV *sv, object_thawer * &v) { v = (object_thawer *)SvPTR_ornull (sv, "cf::object::thawer" ); } |
559 | static inline void sv_to (SV *sv, object_thawer * &v) { v = (object_thawer *) SvPTR_ornull (sv, "cf::object::thawer" ); } |
511 | |
560 | |
512 | //static inline void sv_to (SV *sv, faceinfo * &v) { v = &faces [face_find (SvPV_nolen (sv), 0)]; } |
561 | //static inline void sv_to (SV *sv, faceinfo * &v) { v = &faces [face_find (SvPV_nolen (sv), 0)]; } |
513 | static inline void sv_to (SV *sv, treasurelist * &v) { v = treasurelist::find (SvPV_nolen (sv)); } |
562 | static inline void sv_to (SV *sv, treasurelist * &v) { v = treasurelist::find (SvPV_nolen (sv)); } |
514 | |
563 | |
515 | template<class T> |
564 | template<class T> |
… | |
… | |
2015 | RETVAL |
2064 | RETVAL |
2016 | |
2065 | |
2017 | void |
2066 | void |
2018 | debug_trace (attachable *obj, bool on = true) |
2067 | debug_trace (attachable *obj, bool on = true) |
2019 | CODE: |
2068 | CODE: |
2020 | obj->flags &= ~attachable::F_DEBUG_TRACE; |
2069 | obj->attachable_flags &= ~attachable::F_DEBUG_TRACE; |
2021 | if (on) |
2070 | if (on) |
2022 | obj->flags |= attachable::F_DEBUG_TRACE; |
2071 | obj->attachable_flags |= attachable::F_DEBUG_TRACE; |
2023 | |
2072 | |
2024 | int mortals_size () |
2073 | int mortals_size () |
2025 | CODE: |
2074 | CODE: |
2026 | RETVAL = attachable::mortals.size (); |
2075 | RETVAL = attachable::mortals.size (); |
2027 | OUTPUT: RETVAL |
2076 | OUTPUT: RETVAL |
… | |
… | |
2497 | for (int x = 0; x < THIS->width; ++x) |
2546 | for (int x = 0; x < THIS->width; ++x) |
2498 | for (int y = 0; y < THIS->height; ++y) |
2547 | for (int y = 0; y < THIS->height; ++y) |
2499 | { |
2548 | { |
2500 | for (object *op = THIS->at (x, y).bot; op; op = op->above) |
2549 | for (object *op = THIS->at (x, y).bot; op; op = op->above) |
2501 | if (op->flag [FLAG_IS_FLOOR]) |
2550 | if (op->flag [FLAG_IS_FLOOR]) |
2502 | goto skip_space; |
2551 | goto skip; |
2503 | |
2552 | |
2504 | { |
2553 | { |
2505 | int offs = offset + y * stride + x; |
2554 | int offs = offset + y * stride + x; |
|
|
2555 | |
2506 | if (IN_RANGE_EXC (offs, 0, idxlen)) |
2556 | if (IN_RANGE_EXC (offs, 0, idxlen)) |
2507 | { |
2557 | { |
2508 | if (SV **elem = av_fetch ((AV *)palette, idx [offs], 0)) |
2558 | if (SV **elem = av_fetch ((AV *)palette, idx [offs], 0)) |
2509 | { |
2559 | { |
2510 | object *ob = get_archetype (SvPVutf8_nolen (*elem)); |
2560 | object *ob = get_archetype (SvPVutf8_nolen (*elem)); |
2511 | ob->flag [FLAG_NO_MAP_SAVE] = true; |
2561 | ob->flag [FLAG_NO_MAP_SAVE] = true; |
2512 | THIS->insert (ob, x, y, 0, INS_ABOVE_FLOOR_ONLY); |
2562 | THIS->insert (ob, x, y, 0, INS_ABOVE_FLOOR_ONLY); |
2513 | |
2563 | |
2514 | if (ob->randomitems) |
2564 | if (ob->randomitems && !ob->above) |
2515 | { |
2565 | { |
2516 | if (!ob->above) |
|
|
2517 | { |
|
|
2518 | ob->create_treasure (ob->randomitems); |
2566 | ob->create_treasure (ob->randomitems); |
2519 | |
2567 | |
2520 | for (object *op = ob->above; op; op = op->above) |
2568 | for (object *op = ob->above; op; op = op->above) |
2521 | op->flag [FLAG_NO_MAP_SAVE] = true; |
2569 | op->flag [FLAG_NO_MAP_SAVE] = true; |
2522 | } |
2570 | // TODO: if this is a pickable object, then the item |
2523 | |
2571 | // will at a bit weird - saving inside the player |
2524 | ob->randomitems = 0; |
2572 | // will clear the flag, but when the player drops |
|
|
2573 | // it without logging out, it keeps the flag. |
|
|
2574 | // nobody ahs reported this, but this can be rather |
|
|
2575 | // annoying on persistent maps. |
2525 | } |
2576 | } |
2526 | } |
2577 | } |
2527 | } |
2578 | } |
2528 | } |
2579 | } |
2529 | |
2580 | |
2530 | skip_space: ; |
2581 | skip: ; |
2531 | } |
2582 | } |
2532 | } |
2583 | } |
2533 | |
2584 | |
2534 | void |
2585 | void |
2535 | maptile::set_regiondata (SV *data, int offset, int stride, SV *palette) |
2586 | maptile::set_regiondata (SV *data, int offset, int stride, SV *palette) |
… | |
… | |
2955 | faceinfo *f = face_info (idx); assert (f); |
3006 | faceinfo *f = face_info (idx); assert (f); |
2956 | facedata *d = &(faceset ? f->data64 : f->data32); |
3007 | facedata *d = &(faceset ? f->data64 : f->data32); |
2957 | sv_to (data, d->data); |
3008 | sv_to (data, d->data); |
2958 | STRLEN clen; |
3009 | STRLEN clen; |
2959 | char *cdata = SvPVbyte (chksum, clen); |
3010 | char *cdata = SvPVbyte (chksum, clen); |
2960 | clen = min (CHKSUM_SIZE, clen); |
3011 | clen = min (CHKSUM_MAXLEN, clen); |
2961 | |
3012 | |
2962 | if (memcmp (d->chksum, cdata, clen)) |
3013 | if (clen != d->chksum_len || memcmp (d->chksum, cdata, clen)) |
2963 | { |
3014 | { |
|
|
3015 | d->chksum_len = clen; |
2964 | memcpy (d->chksum, cdata, clen); |
3016 | memcpy (d->chksum, cdata, clen); |
2965 | |
3017 | |
2966 | // invalidate existing client face info |
3018 | // invalidate existing client face info |
2967 | for_all_clients (ns) |
3019 | for_all_clients (ns) |
2968 | if (ns->faceset == faceset) |
3020 | if (ns->faceset == faceset) |
… | |
… | |
2983 | |
3035 | |
2984 | SV *get_chksum (faceidx idx, int faceset = 0) |
3036 | SV *get_chksum (faceidx idx, int faceset = 0) |
2985 | CODE: |
3037 | CODE: |
2986 | facedata *d = face_data (idx, faceset); |
3038 | facedata *d = face_data (idx, faceset); |
2987 | if (!d) XSRETURN_UNDEF; |
3039 | if (!d) XSRETURN_UNDEF; |
2988 | RETVAL = newSVpvn ((char *)d->chksum, CHKSUM_SIZE); |
3040 | RETVAL = newSVpvn ((char *)d->chksum, d->chksum_len); |
2989 | OUTPUT: |
3041 | OUTPUT: |
2990 | RETVAL |
3042 | RETVAL |
2991 | |
3043 | |
2992 | SV *get_data (faceidx idx, int faceset = 0) |
3044 | SV *get_data (faceidx idx, int faceset = 0) |
2993 | CODE: |
3045 | CODE: |