Overview
Comment: | Implement sliding |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
1490be64d59906c78dd6c1d36d2353e6 |
User & Date: | user on 2021-01-03 09:43:55 |
Other Links: | manifest | tags |
Context
2021-01-04
| ||
00:39 | Start to implement replay. (The replay implementation is not yet complete; it doesn't display the replay list anywhere, nor does it save it, nor replay solutions.) check-in: 1c62f22813 user: user tags: trunk | |
2021-01-03
| ||
09:43 | Implement sliding check-in: 1490be64d5 user: user tags: trunk | |
2021-01-01
| ||
04:13 | Change the logic for movement; this way seems to be closer to how it works in Hero Mesh, due to my experiments check-in: c53823977e user: user tags: trunk | |
Changes
Modified class.doc from [4eb22afd16] to [f0b38ad4c2].
︙ | ︙ | |||
1450 1451 1452 1453 1454 1455 1456 | bit22 * Prevents movement regardless of Height, but may still allow sliding. bit23 * Reserved for future. bit24 * | > > | > > | | < > > > | < > > > | 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 | bit22 * Prevents movement regardless of Height, but may still allow sliding. bit23 * Reserved for future. bit24 * Allows sliding to the left regardless of Height; the other attributes still need to be correct (unless bit26 is set). The game engine sets this bit if the Climb/Height is OK for moving. bit25 * Allows sliding to the right regardless of Height; the other attributes still need to be correct (unless bit27 is set). The game engine sets this bit if the Climb/Height is OK for moving. bit26 * Allows hitting to the left regardless of Shape, Volume, etc. In order to actually move when sliding to the left, both bit24 and bit26 must be set, and bit7 must be clear. bit27 * Allows hitting to the right regardless of Shape, Volume, etc. In order to actually move when sliding to the right, both bit25 and bit27 must be set, and bit7 must be clear. bit28 Available for your own use. bit29 Available for your own use. |
︙ | ︙ |
Modified exec.c from [009b283128] to [d29672c800].
︙ | ︙ | |||
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 | } } } // The OF_MOVED flag is set elsewhere, not here o->oflags&=~OF_DONE; return 1; } static int move_dir(Uint32 from,Uint32 obj,Uint32 dir) { // This function is complicated, and there may be mistakes. Object*o; Object*oE; Object*oF; Uint32 objE,objF,objLF,objRF; Uint32 hit=0; Uint32 vol; Value v; if(StackProtection()) Throw("Call stack overflow during movement"); if(obj==VOIDLINK) return 0; o=objects[obj]; o->dir=dir=resolve_dir(obj,dir); if(o->weight>o->inertia) goto fail; o->inertia-=o->weight; restart: if(hit&0x100000) dir=o->dir; objF=obj_dir(obj,dir); if(objF==VOIDLINK) goto fail; | > > > > > > > > > | > > < < | | | 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 | } } } // The OF_MOVED flag is set elsewhere, not here o->oflags&=~OF_DONE; return 1; } static inline int slide_test(Object*o,Object*oF,Uint32 d1,Uint32 d2,Uint32 vol) { // Checks if sliding is possible, except the height of the target location. Uint8 m=(o->shape&(1<<d1))|(oF->shape&(1<<(4^d1))); if(!(m&(m-1))) return 0; if(!(o->shovable&(1<<d2))) return 0; if(height_at(o->x+x_delta[d2],o->y+y_delta[d2])<=o->climb) return 1; return vol+volume_at(o->x+x_delta[d2],o->y+y_delta[d2])<=max_volume; } static int move_dir(Uint32 from,Uint32 obj,Uint32 dir) { // This function is complicated, and there may be mistakes. Object*o; Object*oE; Object*oF; Uint32 objE,objF,objLF,objRF; Uint32 hit=0; Uint32 vol; Value v; if(StackProtection()) Throw("Call stack overflow during movement"); if(obj==VOIDLINK) return 0; o=objects[obj]; o->dir=dir=resolve_dir(obj,dir); if(o->weight>o->inertia) goto fail; o->inertia-=o->weight; restart: if(hit&0x100000) dir=o->dir; objF=obj_dir(obj,dir); if(objF==VOIDLINK) goto fail; if(hit) hit=0x800; oF=objects[objF]; objLF=obj_dir(obj,(dir+1)&7); objRF=obj_dir(obj,(dir-1)&7); if(height_at(oF->x,oF->y)<=o->climb) hit|=0x200000; if(dir&1) { // Diagonal movement hit|=0x80000; vol=o->volume; if(objLF!=VOIDLINK) vol+=volume_at(objects[objLF]->x,objects[objLF]->y); if(objRF!=VOIDLINK) vol+=volume_at(objects[objRF]->x,objects[objRF]->y); if(vol<=max_volume) { objE=objF; while(objE!=VOIDLINK) { if(o->oflags&(OF_DESTROYED|OF_VISUALONLY)) break; oE=objects[objE]; if(oE->height>0) { hit&=0xFC287000; v=send_message(objE,obj,MSG_HIT,NVALUE(oE->x),NVALUE(oE->y),NVALUE(hit)); if(v.t) Throw("Type mismatch in HIT/HITBY"); hit|=v.u&(classes[o->class]->cflags&CF_COMPATIBLE?0xF0098F7F:-1); if(hit&8) goto fail; if(!(hit&0x11)) { v=send_message(obj,objE,MSG_HITBY,NVALUE(o->x),NVALUE(o->y),NVALUE(hit)); if(v.t) Throw("Type mismatch in HIT/HITBY"); hit|=v.u&(classes[oE->class]->cflags&CF_COMPATIBLE?0xF0098F7F:-1); if(hit&8) goto fail; } } objE=obj_below(objE); } if((hit&0x200000) && !(hit&0x402008)) { if(hit&0x20000) goto success; |
︙ | ︙ | |||
808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 | } objE=obj_below(objE); } } } else { // Orthogonal movement if(!oF) goto fail; objE=objF; while(objE!=VOIDLINK) { if(o->oflags&(OF_DESTROYED|OF_VISUALONLY)) break; oE=objects[objE]; if(oE->height>0) { hit&=~7; // HIT/HITBY messages v=send_message(objE,obj,MSG_HIT,NVALUE(oE->x),NVALUE(oE->y),NVALUE(hit)); if(v.t) Throw("Type mismatch in HIT/HITBY"); | > > > > > > > > > > > > > > | | | 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 | } objE=obj_below(objE); } } } else { // Orthogonal movement if(!oF) goto fail; if(o->shape) { // Check if attributes allow sliding vol=o->volume+volume_at(oF->x,oF->y); if(objLF!=VOIDLINK && slide_test(o,oF,dir,(dir+2)&7,vol)) { hit|=0x4000000; oE=objects[objLF]; if(height_at(oE->x,oE->y)<=o->climb) hit|=0x1000000; } if(objRF!=VOIDLINK && slide_test(o,oF,dir|1,(dir-2)&7,vol)) { hit|=0x8000000; oE=objects[objRF]; if(height_at(oE->x,oE->y)<=o->climb) hit|=0x2000000; } } objE=objF; while(objE!=VOIDLINK) { if(o->oflags&(OF_DESTROYED|OF_VISUALONLY)) break; oE=objects[objE]; if(oE->height>0) { hit&=~7; // HIT/HITBY messages v=send_message(objE,obj,MSG_HIT,NVALUE(oE->x),NVALUE(oE->y),NVALUE(hit)); if(v.t) Throw("Type mismatch in HIT/HITBY"); hit|=v.u&(classes[o->class]->cflags&CF_COMPATIBLE?0xF0098F7F:-1); if(hit&8) goto fail; if(!(hit&0x11)) { v=send_message(obj,objE,MSG_HITBY,NVALUE(o->x),NVALUE(o->y),NVALUE(hit)); if(v.t) Throw("Type mismatch in HIT/HITBY"); hit|=v.u&(classes[oE->class]->cflags&CF_COMPATIBLE?0xF0098F7F:-1); } if(hit&0x108) goto fail; // Hardness/sharpness if(!(hit&0x22)) { if(o->sharp[dir>>1]>oE->hard[(dir^4)>>1] && !v_bool(destroy(obj,objE,2))) hit|=0x8004; if(oE->sharp[(dir^4)>>1]>o->hard[dir>>1] && !v_bool(destroy(objE,obj,1))) hit|=0x4C; } |
︙ | ︙ | |||
852 853 854 855 856 857 858 | if((hit&0x200000) && !(hit&0x400000)) { if(hit&0x20000) goto success; if(move_to(from,obj,oF->x,oF->y)) goto success; else goto fail; } // Sliding if(hit&0x80) goto fail; hit|=0x10000; | > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 | if((hit&0x200000) && !(hit&0x400000)) { if(hit&0x20000) goto success; if(move_to(from,obj,oF->x,oF->y)) goto success; else goto fail; } // Sliding if(hit&0x80) goto fail; hit|=0x10000; if(hit&0x8000000) { hit&=0xF010000; objE=objRF; while(objE!=VOIDLINK) { if(o->oflags&(OF_DESTROYED|OF_VISUALONLY)) break; oE=objects[objE]; if(oE->height>0) { hit&=~7; // HIT/HITBY messages v=send_message(objE,obj,MSG_HIT,NVALUE(oE->x),NVALUE(oE->y),NVALUE(hit)); if(v.t) Throw("Type mismatch in HIT/HITBY"); hit|=v.u&(classes[o->class]->cflags&CF_COMPATIBLE?0xF0098F7F:-1); if(hit&8) goto otherside; if(!(hit&0x11)) { v=send_message(obj,objE,MSG_HITBY,NVALUE(o->x),NVALUE(o->y),NVALUE(hit)); if(v.t) Throw("Type mismatch in HIT/HITBY"); hit|=v.u&(classes[oE->class]->cflags&CF_COMPATIBLE?0xF0098F7F:-1); } if(hit&0x108) goto otherside; // Hardness/sharpness if(!(hit&0x22)) { if(o->sharp[dir>>1]>oE->hard[(dir^4)>>1] && !v_bool(destroy(obj,objE,2))) hit|=0x8004; if(oE->sharp[(dir^4)>>1]>o->hard[dir>>1] && !v_bool(destroy(objE,obj,1))) hit|=0x4C; } } if(hit&0x600) goto otherside; objE=obj_below(objE); } if((hit&0x48000)==0x8000) goto restart; if((hit&0x2000000) && !(hit&0x400080)) { if(hit&0x20000) goto success; if(move_to(from,obj,objects[objRF]->x,objects[objRF]->y)) goto success; } } otherside: if(hit&0x4000000) { hit&=0xF010000; objE=objLF; while(objE!=VOIDLINK) { if(o->oflags&(OF_DESTROYED|OF_VISUALONLY)) break; oE=objects[objE]; if(oE->height>0) { hit&=~7; // HIT/HITBY messages v=send_message(objE,obj,MSG_HIT,NVALUE(oE->x),NVALUE(oE->y),NVALUE(hit)); if(v.t) Throw("Type mismatch in HIT/HITBY"); hit|=v.u&(classes[o->class]->cflags&CF_COMPATIBLE?0xF0098F7F:-1); if(hit&8) goto fail; if(!(hit&0x11)) { v=send_message(obj,objE,MSG_HITBY,NVALUE(o->x),NVALUE(o->y),NVALUE(hit)); if(v.t) Throw("Type mismatch in HIT/HITBY"); hit|=v.u&(classes[oE->class]->cflags&CF_COMPATIBLE?0xF0098F7F:-1); } if(hit&0x108) goto fail; // Hardness/sharpness if(!(hit&0x22)) { if(o->sharp[dir>>1]>oE->hard[(dir^4)>>1] && !v_bool(destroy(obj,objE,2))) hit|=0x8004; if(oE->sharp[(dir^4)>>1]>o->hard[dir>>1] && !v_bool(destroy(objE,obj,1))) hit|=0x4C; } } if(hit&0x600) goto fail; objE=obj_below(objE); } if((hit&0x48000)==0x8000) goto restart; if((hit&0x1000000) && !(hit&0x400080)) { if(hit&0x20000) goto success; if(move_to(from,obj,objects[objLF]->x,objects[objLF]->y)) goto success; } } } fail: if(hit&0x1000) goto success; o->inertia=0; return 0; success: if(!(hit&0x4000)) o->oflags|=OF_MOVED; return 1; } static int jump_to(Uint32 from,Uint32 n,Uint32 x,Uint32 y) { int xx,yy; |
︙ | ︙ |