1 | /* |
1 | /* |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
4 | * Copyright (©) 2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
4 | * Copyright (©) 2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2006,2007 by Marc Lehmann <cf@schmorp.de> |
|
|
6 | * |
5 | * |
7 | * Deliantra is free software: you can redistribute it and/or modify it under |
6 | * Deliantra is free software: you can redistribute it and/or modify it under |
8 | * the terms of the Affero GNU General Public License as published by the |
7 | * the terms of the Affero GNU General Public License as published by the |
9 | * Free Software Foundation, either version 3 of the License, or (at your |
8 | * Free Software Foundation, either version 3 of the License, or (at your |
10 | * option) any later version. |
9 | * option) any later version. |
… | |
… | |
402 | hv_clear ((HV *)sv); |
401 | hv_clear ((HV *)sv); |
403 | sv_unmagic (sv, PERL_MAGIC_ext); |
402 | sv_unmagic (sv, PERL_MAGIC_ext); |
404 | } |
403 | } |
405 | #endif |
404 | #endif |
406 | |
405 | |
407 | static long SvPTR_nc (SV *sv) |
406 | static long |
|
|
407 | SvPTR_nc (SV *sv) |
408 | { |
408 | { |
409 | sv = SvRV (sv); |
409 | sv = SvRV (sv); |
410 | |
410 | |
411 | // very important shortcut |
411 | // very important shortcut |
412 | if (expect_true (SvMAGIC (sv)->mg_type == PERL_MAGIC_ext)) |
412 | if (expect_true (SvMAGIC (sv) && SvMAGIC (sv)->mg_type == PERL_MAGIC_ext)) |
413 | return (long)SvMAGIC (sv)->mg_ptr; |
413 | return (long)SvMAGIC (sv)->mg_ptr; |
414 | |
414 | |
415 | if (MAGIC *mg = mg_find (sv, PERL_MAGIC_ext)) |
415 | if (MAGIC *mg = mg_find (sv, PERL_MAGIC_ext)) |
416 | return (long)mg->mg_ptr; |
416 | return (long)mg->mg_ptr; |
417 | |
417 | |
… | |
… | |
470 | |
470 | |
471 | if (!SvROK (sv) |
471 | if (!SvROK (sv) |
472 | || (SvSTASH (SvRV (sv)) != stash_cf_player_wrap |
472 | || (SvSTASH (SvRV (sv)) != stash_cf_player_wrap |
473 | && !sv_derived_from (sv, "cf::player"))) |
473 | && !sv_derived_from (sv, "cf::player"))) |
474 | croak ("object of type cf::player expected"); |
474 | croak ("object of type cf::player expected"); |
475 | |
|
|
476 | if (SvSTASH (SvRV (sv)) != stash_cf_player_wrap) |
|
|
477 | printf ("unexpected stash %s:%s\n", HvNAME(SvSTASH(SvRV(sv))));//D |
|
|
478 | |
|
|
479 | |
475 | |
480 | return SvPTR_nc (sv); |
476 | return SvPTR_nc (sv); |
481 | } |
477 | } |
482 | |
478 | |
483 | 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); } |
… | |
… | |
2550 | for (int x = 0; x < THIS->width; ++x) |
2546 | for (int x = 0; x < THIS->width; ++x) |
2551 | for (int y = 0; y < THIS->height; ++y) |
2547 | for (int y = 0; y < THIS->height; ++y) |
2552 | { |
2548 | { |
2553 | 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) |
2554 | if (op->flag [FLAG_IS_FLOOR]) |
2550 | if (op->flag [FLAG_IS_FLOOR]) |
2555 | goto skip_space; |
2551 | goto skip; |
2556 | |
2552 | |
2557 | { |
2553 | { |
2558 | int offs = offset + y * stride + x; |
2554 | int offs = offset + y * stride + x; |
|
|
2555 | |
2559 | if (IN_RANGE_EXC (offs, 0, idxlen)) |
2556 | if (IN_RANGE_EXC (offs, 0, idxlen)) |
2560 | { |
2557 | { |
2561 | if (SV **elem = av_fetch ((AV *)palette, idx [offs], 0)) |
2558 | if (SV **elem = av_fetch ((AV *)palette, idx [offs], 0)) |
2562 | { |
2559 | { |
2563 | object *ob = get_archetype (SvPVutf8_nolen (*elem)); |
2560 | object *ob = get_archetype (SvPVutf8_nolen (*elem)); |
2564 | ob->flag [FLAG_NO_MAP_SAVE] = true; |
2561 | ob->flag [FLAG_NO_MAP_SAVE] = true; |
2565 | THIS->insert (ob, x, y, 0, INS_ABOVE_FLOOR_ONLY); |
2562 | THIS->insert (ob, x, y, 0, INS_ABOVE_FLOOR_ONLY); |
2566 | |
2563 | |
2567 | if (ob->randomitems) |
2564 | if (ob->randomitems && !ob->above) |
2568 | { |
2565 | { |
2569 | if (!ob->above) |
|
|
2570 | { |
|
|
2571 | ob->create_treasure (ob->randomitems); |
2566 | ob->create_treasure (ob->randomitems); |
2572 | |
2567 | |
2573 | for (object *op = ob->above; op; op = op->above) |
2568 | for (object *op = ob->above; op; op = op->above) |
2574 | op->flag [FLAG_NO_MAP_SAVE] = true; |
2569 | op->flag [FLAG_NO_MAP_SAVE] = true; |
2575 | } |
2570 | // TODO: if this is a pickable object, then the item |
2576 | |
2571 | // will at a bit weird - saving inside the player |
2577 | 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. |
2578 | } |
2576 | } |
2579 | } |
2577 | } |
2580 | } |
2578 | } |
2581 | } |
2579 | } |
2582 | |
2580 | |
2583 | skip_space: ; |
2581 | skip: ; |
2584 | } |
2582 | } |
2585 | } |
2583 | } |
2586 | |
2584 | |
2587 | void |
2585 | void |
2588 | maptile::set_regiondata (SV *data, int offset, int stride, SV *palette) |
2586 | maptile::set_regiondata (SV *data, int offset, int stride, SV *palette) |
… | |
… | |
2833 | archetype *archetypes (U32 index) |
2831 | archetype *archetypes (U32 index) |
2834 | CODE: |
2832 | CODE: |
2835 | RETVAL = index < archetypes.size () ? archetypes [index] : 0; |
2833 | RETVAL = index < archetypes.size () ? archetypes [index] : 0; |
2836 | OUTPUT: RETVAL |
2834 | OUTPUT: RETVAL |
2837 | |
2835 | |
2838 | object *instantiate (archetype *arch) |
|
|
2839 | CODE: |
|
|
2840 | RETVAL = arch_to_object (arch); |
|
|
2841 | OUTPUT: |
|
|
2842 | RETVAL |
|
|
2843 | |
|
|
2844 | INCLUDE: $PERL $srcdir/genacc archetype ../include/object.h | |
2836 | INCLUDE: $PERL $srcdir/genacc archetype ../include/object.h | |
2845 | |
2837 | |
2846 | MODULE = cf PACKAGE = cf::party |
2838 | MODULE = cf PACKAGE = cf::party |
2847 | |
2839 | |
2848 | partylist *first () |
2840 | partylist *first () |
… | |
… | |
3008 | faceinfo *f = face_info (idx); assert (f); |
3000 | faceinfo *f = face_info (idx); assert (f); |
3009 | facedata *d = &(faceset ? f->data64 : f->data32); |
3001 | facedata *d = &(faceset ? f->data64 : f->data32); |
3010 | sv_to (data, d->data); |
3002 | sv_to (data, d->data); |
3011 | STRLEN clen; |
3003 | STRLEN clen; |
3012 | char *cdata = SvPVbyte (chksum, clen); |
3004 | char *cdata = SvPVbyte (chksum, clen); |
3013 | clen = min (CHKSUM_SIZE, clen); |
3005 | clen = min (CHKSUM_MAXLEN, clen); |
3014 | |
3006 | |
|
|
3007 | assert (("cf::face::set_data must be called with a non-empty checksum", clen)); |
|
|
3008 | |
3015 | if (memcmp (d->chksum, cdata, clen)) |
3009 | if (clen != d->chksum_len || memcmp (d->chksum, cdata, clen)) |
3016 | { |
3010 | { |
|
|
3011 | d->chksum_len = clen; |
3017 | memcpy (d->chksum, cdata, clen); |
3012 | memcpy (d->chksum, cdata, clen); |
3018 | |
3013 | |
3019 | // invalidate existing client face info |
3014 | // invalidate existing client face info |
3020 | for_all_clients (ns) |
3015 | for_all_clients (ns) |
3021 | if (ns->faceset == faceset) |
3016 | if (ns->faceset == faceset) |
… | |
… | |
3036 | |
3031 | |
3037 | SV *get_chksum (faceidx idx, int faceset = 0) |
3032 | SV *get_chksum (faceidx idx, int faceset = 0) |
3038 | CODE: |
3033 | CODE: |
3039 | facedata *d = face_data (idx, faceset); |
3034 | facedata *d = face_data (idx, faceset); |
3040 | if (!d) XSRETURN_UNDEF; |
3035 | if (!d) XSRETURN_UNDEF; |
3041 | RETVAL = newSVpvn ((char *)d->chksum, CHKSUM_SIZE); |
3036 | RETVAL = newSVpvn ((char *)d->chksum, d->chksum_len); |
3042 | OUTPUT: |
3037 | OUTPUT: |
3043 | RETVAL |
3038 | RETVAL |
3044 | |
3039 | |
3045 | SV *get_data (faceidx idx, int faceset = 0) |
3040 | SV *get_data (faceidx idx, int faceset = 0) |
3046 | CODE: |
3041 | CODE: |