├── .gitignore ├── LICENSE.txt ├── README.md ├── examples ├── mcpi_import_3d_model.py ├── mcpi_pixel_art.py ├── mcpi_pyramid_algorithm.py ├── mcpi_superpowers.py ├── minecraftstuff_drawing.py ├── minecraftstuff_shapes.py ├── minecraftstuff_shapes_rotation.py ├── resources │ ├── farmhouse.obj │ ├── mario.gif │ ├── shuttle.obj │ └── skyscraper.obj ├── turtle_3dfractaltree.py ├── turtle_3dfractaltree_colors.py ├── turtle_3dnautilus.py ├── turtle_adventuresinrpi.py ├── turtle_circle.py ├── turtle_fractaltree.py ├── turtle_pattern.py ├── turtle_spiral.py └── turtle_squares.py ├── lesson1_setup.py ├── mcpi ├── __init__.py ├── block.py ├── connection.py ├── event.py ├── minecraft.py ├── util.py └── vec3.py ├── minecraftstuff ├── __init__.py └── minecraftstuff.py └── script.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 2 | 3 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TeachCraft-Examples 2 | 3 | ## Examples 4 | 5 | Checkout the /examples directory in this repo! 6 | 7 | 8 | ## MCPI library (TeachCraft version) 9 | 10 | Click a function name to see an example. 11 | 12 |
13 | 14 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 15 | 16 | 17 | > Connect to a minecraft world 18 | 19 | ```python 20 | 21 | from mcpi import minecraft 22 | 23 | #Connect to minecraft server 127.0.0.1 as player 'steve' 24 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 25 | 26 | #Get current player's position 27 | pos = mc.player.getPos() 28 | print pos.x, pos.y, pos.z 29 | 30 | ``` 31 | 32 |
33 | 34 |
35 | 36 | mc.setBlock(x, y, z, block_id, [block_data]) 37 | 38 | 39 | > Set the block at coordinates X/Y/Z to block_id 40 | 41 | ```python 42 | 43 | from mcpi import minecraft 44 | 45 | #Connect to minecraft server 127.0.0.1 as player 'steve' 46 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 47 | 48 | #Get current player's position 49 | pos = mc.player.getPos() 50 | 51 | #This is the minecraft block ID of the glass block. 52 | #To see what other block IDs are available, go here in your browser: http://minecraft-ids.grahamedgecombe.com/ 53 | glass_block_id = 20 54 | 55 | #Set the block underneath the player to be glass 56 | mc.setBlock(pos.x, pos.y-1, pos.z, glass_block_id) 57 | 58 | #Set the block to the side of player to be wood of a specific subtype 59 | wood_block_id = 5 60 | wood_data = 1 #subtype 61 | mc.setBlock(pos.x+1, pos.y, pos.z, wood_block_id, wood_data) 62 | 63 | ``` 64 | 65 |
66 | 67 |
68 | 69 | mc.getBlock(x, y, z) 70 | 71 | 72 | > Get the block at coordinates X/Y/Z, returning its block ID 73 | 74 | ```python 75 | 76 | from mcpi import minecraft 77 | 78 | # Connect to minecraft server 127.0.0.1 as player 'steve' 79 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 80 | 81 | # Get current player's position 82 | pos = mc.player.getPos() 83 | 84 | # Get the block underneath the player 85 | block_id_under_player = mc.getBlock(pos.x, pos.y-1, pos.z) 86 | grass_block_id = 2 87 | 88 | if block_id_under_player == grass_block_id: 89 | print "Player is standing on grass" 90 | 91 | ``` 92 | 93 |
94 | 95 | 96 | 97 |
98 | 99 | mc.getBlockWithData(x, y, z) 100 | 101 | 102 | > Get the block at coordinates X/Y/Z, returning its block ID & data field (e.g. for wool color) 103 | 104 | ```python 105 | 106 | from mcpi import minecraft 107 | 108 | # Connect to minecraft server 127.0.0.1 as player 'steve' 109 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 110 | 111 | # Get current player's position 112 | pos = mc.player.getPos() 113 | 114 | # Get the block underneath the player 115 | block_under_player = mc.getBlockWithData(pos.x, pos.y-1, pos.z) 116 | print "block id", block_under_player.id 117 | print "block data", block_under_player.data 118 | 119 | ``` 120 | 121 |
122 | 123 | 124 |
125 | 126 | mc.setBlocks(x1, y1, z1, x2, y2, z2, block_id, [block_data]) 127 | 128 | 129 | > Set a cuboid of blocks between two opposite corners (x1/y1/z1 and x2/y2/z2) 130 | 131 | ```python 132 | 133 | from mcpi import minecraft 134 | 135 | #Connect to minecraft server 127.0.0.1 as player 'steve' 136 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 137 | 138 | #Get current player's position 139 | pos = mc.player.getPos() 140 | 141 | #This is the minecraft block ID of the glass block. 142 | #To see what other block IDs are available, go here in your browser: http://minecraft-ids.grahamedgecombe.com/ 143 | glass_block_id = 20 144 | 145 | #Build a glass cube next to the player 146 | mc.setBlocks(pos.x+3, pos.y, pos.z, pos.x+8, pos.y+5, pos.z+5, glass_block_id) 147 | 148 | #Build a wood cube of a specific subtype next to the player, then make it hollow by building a smaller cube of air inside 149 | wood_block_id = 5 150 | wood_data = 1 #subtype 151 | mc.setBlocks(pos.x-3, pos.y, pos.z, pos.x-8, pos.y+5, pos.z-5, wood_block_id, wood_data) 152 | 153 | air_block_id = 0 154 | mc.setBlocks(pos.x-2, pos.y+1, pos.z-1, pos.x-7, pos.y+4, pos.z-4, air_block_id) 155 | 156 | ``` 157 | 158 |
159 | 160 | 161 |
162 | 163 | mc.getBlocks(x1, y1, z1, x2, y2, z2) 164 | 165 | 166 | > Get a cuboid of blocks between two opposite corners (x1/y1/z1 and x2/y2/z2) 167 | 168 | ```python 169 | 170 | from mcpi import minecraft 171 | 172 | #Connect to minecraft server 127.0.0.1 as player 'steve' 173 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 174 | 175 | #Get current player's position 176 | pos = mc.player.getPos() 177 | 178 | blocks = mc.getBlocks(pos.x+3, pos.y, pos.z, pos.x+8, pos.y+5, pos.z+5) 179 | for block_id in blocks: 180 | print block_id 181 | 182 | 183 | ``` 184 | 185 |
186 | 187 | 188 |
189 | 190 | mc.player.getPos() 191 | 192 | 193 | > Get current player's position exactly (decimals) 194 | 195 | ```python 196 | 197 | from mcpi import minecraft 198 | 199 | #Connect to minecraft server 127.0.0.1 as player 'steve' 200 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="bob") 201 | 202 | #Get current player's position 203 | pos = mc.player.getPos() 204 | 205 | # Returns Vec3(18.3814903971,6.0,25.6063951368) 206 | # Can be accessed as pos.x, pos.y, and pos.z 207 | print pos.x, pos.y, pos.z 208 | 209 | ``` 210 | 211 |
212 | 213 | 214 |
215 | 216 | mc.player.setPos(x, y, z) 217 | 218 | 219 | > Set current player's position exactly (supports decimals) 220 | 221 | ```python 222 | 223 | from mcpi import minecraft 224 | 225 | #Connect to minecraft server 127.0.0.1 as player 'steve' 226 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="bob") 227 | 228 | #Get current player's position 229 | pos = mc.player.getPos() 230 | 231 | #Set current player's position 100 blocks in the air 232 | mc.player.setPos(pos.x, pos.y+100, pos.z) 233 | 234 | ``` 235 | 236 |
237 | 238 |
239 | 240 | mc.player.getTilePos() 241 | 242 | 243 | > Get current player's position rounded to the block (integer) 244 | 245 | ```python 246 | 247 | from mcpi import minecraft 248 | 249 | #Connect to minecraft server 127.0.0.1 as player 'steve' 250 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="bob") 251 | 252 | #Get current player's position 253 | pos = mc.player.getTilePos() 254 | 255 | # Returns Vec3(52, 4, -10) 256 | # Can be accessed as pos.x, pos.y, and pos.z 257 | print pos.x, pos.y, pos.z 258 | 259 | ``` 260 | 261 |
262 | 263 | 264 |
265 | 266 | mc.player.setTilePos(x, y, z) 267 | 268 | 269 | > Set current player's position rounded to the block (supports integers) 270 | 271 | ```python 272 | 273 | from mcpi import minecraft 274 | 275 | #Connect to minecraft server 127.0.0.1 as player 'steve' 276 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="bob") 277 | 278 | #Get current player's position 279 | pos = mc.player.getTilePos() 280 | 281 | #Set current player's position 100 blocks in the air 282 | mc.player.setTilePos(pos.x, pos.y+100, pos.z) 283 | 284 | ``` 285 | 286 |
287 | 288 | 289 |
290 | 291 | mc.getHeight(x, z) 292 | 293 | 294 | > Given an x/z coordinate, find the highest non-air block (y coordinate) 295 | 296 | ```python 297 | 298 | from mcpi import minecraft 299 | 300 | #Connect to minecraft server 127.0.0.1 as player 'steve' 301 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="bob") 302 | 303 | #Get current player's position 304 | pos = mc.player.getTilePos() 305 | 306 | highest_block_y_coordinate = mc.getHeight(pos.x, pos.y) 307 | print highest_block_y_coordinate 308 | 309 | ``` 310 | 311 |
312 | 313 |
314 | 315 | mc.postToChat("Hello World!") 316 | 317 | 318 | > Post any text string to chat in-game 319 | 320 | ```python 321 | 322 | from mcpi import minecraft 323 | 324 | #Connect to minecraft server 127.0.0.1 as player 'steve' 325 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="bob") 326 | 327 | mc.postToChat("Hello World!") 328 | 329 | ``` 330 | 331 |
332 | 333 | 334 |
335 | 336 | mc.player.pollBlockHits() 337 | 338 | 339 | > Perform an action wherever the player right clicks with a sword 340 | 341 | ```python 342 | 343 | from mcpi import minecraft 344 | 345 | #Connect to minecraft server 127.0.0.1 as player 'steve' 346 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="bob") 347 | 348 | while True: 349 | 350 | for blockhit in mc.player.pollBlockHits(): 351 | 352 | #Get coordinates for block that player right clicked with sword 353 | pos = blockhit.pos 354 | 355 | #Clear out a cube of blocks at that location 356 | air_block_id = 0 357 | mc.setBlocks(pos.x+2, pos.y+2, pos.z+2, pos.x-2, pos.y-2, pos.z-2, air_block_id) 358 | 359 | ``` 360 | 361 |
362 | 363 |
364 | 365 | mc.player.pollProjectileHits() 366 | 367 | 368 | > Perform an action wherever the player shoots with an arrow 369 | 370 | ```python 371 | 372 | from mcpi import minecraft 373 | 374 | #Connect to minecraft server 127.0.0.1 as player 'steve' 375 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="bob") 376 | 377 | while True: 378 | 379 | for blockhit in mc.player.pollProjectileHits(): 380 | 381 | #Get coordinates for block that player shot with an arrow 382 | pos = blockhit.pos 383 | 384 | #Teleport player to where arrow landed 385 | mc.player.setPos(pos.x, pos.y, pos.z) 386 | 387 | ``` 388 | 389 |
390 | 391 |
392 | 393 | mc.player.pollChatPosts() 394 | 395 | 396 | > Perform an action whenever the player types something in chat 397 | 398 | ```python 399 | 400 | from mcpi import minecraft 401 | 402 | #Connect to minecraft server 127.0.0.1 as player 'steve' 403 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="bob") 404 | 405 | while True: 406 | 407 | for chatpost in mc.player.pollChatPosts(): 408 | 409 | #If I type explode into chat... 410 | if chatpost.message.lower() == "explode": 411 | 412 | #Get my position 413 | pos = mc.player.getPos() 414 | 415 | #Put TNT at my position 416 | mc.setBlock(pos.x, pos.y, pos.z, 46) 417 | 418 | #And put a redstone block under the TNT to activate it 419 | mc.setBlock(pos.x, pos.y-1, pos.z, 152) 420 | 421 | ``` 422 | 423 |
424 | 425 | 426 |
427 | 428 | mc.events.clearAll() 429 | 430 | 431 | > Clear all events that have happened since the events where last retrieved 432 | 433 | ```python 434 | 435 | from mcpi import minecraft 436 | 437 | #Connect to minecraft server 127.0.0.1 as player 'steve' 438 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="bob") 439 | 440 | mc.events.clearAll() 441 | 442 | ``` 443 | 444 |
445 | 446 | 447 |
448 | 449 | mc.player.getDirection() 450 | 451 | 452 | > Get unit vector of x,y,z for the player's direction 453 | 454 | ```python 455 | 456 | from mcpi import minecraft 457 | 458 | #Connect to minecraft server 127.0.0.1 as player 'steve' 459 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="bob") 460 | 461 | #Get current player's direction 462 | direction = mc.player.getDirection() 463 | 464 | # Returns Vec3(-0.935271308082,-0.271442436324,-0.227126801679) 465 | # Can be accessed as direction.x, direction.y, and direction.z 466 | print direction.x, direction.y, direction.z 467 | 468 | ``` 469 | 470 |
471 | 472 |
473 | 474 | mc.player.getPitch() 475 | 476 | 477 | > Get the pitch angle (-90 to 90) for the player 478 | 479 | ```python 480 | 481 | from mcpi import minecraft 482 | 483 | #Connect to minecraft server 127.0.0.1 as player 'steve' 484 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="bob") 485 | 486 | #Get current player's pitch 487 | pitch = mc.player.getPitch() 488 | 489 | # Returns 15.750118 (or something like that) 490 | print pitch 491 | 492 | ``` 493 | 494 |
495 | 496 |
497 | 498 | mc.player.getRotation() 499 | 500 | 501 | > Get the rotational angle (0 to 360) for the player 502 | 503 | ```python 504 | 505 | from mcpi import minecraft 506 | 507 | #Connect to minecraft server 127.0.0.1 as player 'steve' 508 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="bob") 509 | 510 | #Get current player's rotation 511 | rotation = mc.player.getRotation() 512 | 513 | # Returns -256.3502 (or something like that) 514 | print rotation 515 | 516 | ``` 517 | 518 |
519 | 520 | 521 | ## minecraftstuff library [From Martin O'Hanlon, repo, website, book] 522 | 523 | #### minecraftstuff.MinecraftTurtle 524 | 525 | - Official Documentation 526 | 527 |
528 | 529 | turtle = MinecraftTurtle(mc, pos) 530 | 531 | 532 | > Create a Minecraft Turtle 533 | 534 | ```python 535 | 536 | from mcpi import minecraft 537 | from minecraftstuff import MinecraftTurtle 538 | 539 | #Connect to minecraft server 127.0.0.1 as player 'steve' 540 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 541 | 542 | #Get current player's position 543 | pos = mc.player.getPos() 544 | 545 | 546 | # create minecraft turtle 547 | turtle = MinecraftTurtle(mc, pos) 548 | 549 | ``` 550 | 551 |
552 | 553 | 554 |
555 | 556 | turtle.forward(distance) 557 | 558 | 559 | > Move turtle forward [distance] number of blocks 560 | 561 | ```python 562 | 563 | from mcpi import minecraft 564 | from minecraftstuff import MinecraftTurtle 565 | 566 | #Connect to minecraft server 127.0.0.1 as player 'steve' 567 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 568 | 569 | #Get current player's position 570 | pos = mc.player.getPos() 571 | 572 | 573 | # create minecraft turtle 574 | turtle = MinecraftTurtle(mc, pos) 575 | 576 | # Move turtle forward 5 blocks 577 | turtle.forward(5) 578 | 579 | ``` 580 | 581 |
582 | 583 |
584 | 585 | turtle.backward(distance) 586 | 587 | 588 | > Move turtle backward [distance] number of blocks 589 | 590 | ```python 591 | 592 | from mcpi import minecraft 593 | from minecraftstuff import MinecraftTurtle 594 | 595 | #Connect to minecraft server 127.0.0.1 as player 'steve' 596 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 597 | 598 | #Get current player's position 599 | pos = mc.player.getPos() 600 | 601 | 602 | # create minecraft turtle 603 | turtle = MinecraftTurtle(mc, pos) 604 | 605 | turtle.backward(10) 606 | 607 | ``` 608 | 609 |
610 | 611 |
612 | 613 | turtle.right(distance) 614 | 615 | 616 | > Move turtle right [distance] number of blocks 617 | 618 | ```python 619 | 620 | from mcpi import minecraft 621 | from minecraftstuff import MinecraftTurtle 622 | 623 | #Connect to minecraft server 127.0.0.1 as player 'steve' 624 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 625 | 626 | #Get current player's position 627 | pos = mc.player.getPos() 628 | 629 | 630 | # create minecraft turtle 631 | turtle = MinecraftTurtle(mc, pos) 632 | 633 | turtle.right(10) 634 | 635 | ``` 636 | 637 |
638 | 639 |
640 | 641 | turtle.left(distance) 642 | 643 | 644 | > Move turtle left [distance] number of blocks 645 | 646 | ```python 647 | 648 | from mcpi import minecraft 649 | from minecraftstuff import MinecraftTurtle 650 | 651 | #Connect to minecraft server 127.0.0.1 as player 'steve' 652 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 653 | 654 | #Get current player's position 655 | pos = mc.player.getPos() 656 | 657 | 658 | # create minecraft turtle 659 | turtle = MinecraftTurtle(mc, pos) 660 | 661 | turtle.left(10) 662 | 663 | ``` 664 | 665 |
666 | 667 | 668 |
669 | 670 | turtle.up(distance) 671 | 672 | 673 | > Move turtle up [distance] number of blocks 674 | 675 | ```python 676 | 677 | from mcpi import minecraft 678 | from minecraftstuff import MinecraftTurtle 679 | 680 | #Connect to minecraft server 127.0.0.1 as player 'steve' 681 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 682 | 683 | #Get current player's position 684 | pos = mc.player.getPos() 685 | 686 | 687 | # create minecraft turtle 688 | turtle = MinecraftTurtle(mc, pos) 689 | 690 | turtle.up(10) 691 | 692 | ``` 693 | 694 |
695 | 696 |
697 | 698 | turtle.down(distance) 699 | 700 | 701 | > Move turtle down [distance] number of blocks 702 | 703 | ```python 704 | 705 | from mcpi import minecraft 706 | from minecraftstuff import MinecraftTurtle 707 | 708 | #Connect to minecraft server 127.0.0.1 as player 'steve' 709 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 710 | 711 | #Get current player's position 712 | pos = mc.player.getPos() 713 | 714 | 715 | # create minecraft turtle 716 | turtle = MinecraftTurtle(mc, pos) 717 | 718 | turtle.down(10) 719 | 720 | ``` 721 | 722 |
723 | 724 |
725 | 726 | turtle.home() 727 | 728 | 729 | > Move turtle back to the position it started in 730 | 731 | ```python 732 | 733 | from mcpi import minecraft 734 | from minecraftstuff import MinecraftTurtle 735 | 736 | #Connect to minecraft server 127.0.0.1 as player 'steve' 737 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 738 | 739 | #Get current player's position 740 | pos = mc.player.getPos() 741 | 742 | 743 | # create minecraft turtle 744 | turtle = MinecraftTurtle(mc, pos) 745 | 746 | turtle.down(10) 747 | turtle.right(10) 748 | turtle.home() 749 | 750 | ``` 751 | 752 |
753 | 754 |
755 | 756 | turtle.speed(integer) 757 | 758 | 759 | > Change the turtles speed (1 - slowest, 10 - fastest, 0 - no animation, it just draws the lines) 760 | 761 | ```python 762 | 763 | from mcpi import minecraft 764 | from minecraftstuff import MinecraftTurtle 765 | 766 | #Connect to minecraft server 127.0.0.1 as player 'steve' 767 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 768 | 769 | #Get current player's position 770 | pos = mc.player.getPos() 771 | 772 | 773 | # create minecraft turtle 774 | turtle = MinecraftTurtle(mc, pos) 775 | 776 | turtle.speed(5) 777 | turtle.down(10) 778 | turtle.speed(10) 779 | turtle.right(10) 780 | turtle.home() 781 | 782 | ``` 783 | 784 |
785 | 786 | 787 |
788 | 789 | turtle.penblock(block_id, [block_data]) 790 | 791 | 792 | > Change the turtles speed (1 - slowest, 10 - fastest, 0 - no animation, it just draws the lines) 793 | 794 | ```python 795 | 796 | from mcpi import minecraft 797 | from minecraftstuff import MinecraftTurtle 798 | 799 | #Connect to minecraft server 127.0.0.1 as player 'steve' 800 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 801 | 802 | #Get current player's position 803 | pos = mc.player.getPos() 804 | 805 | 806 | # create minecraft turtle 807 | turtle = MinecraftTurtle(mc, pos) 808 | 809 | grass_block_id = 2 810 | turtle.penblock(grass_block_id) 811 | turtle.down(10) 812 | 813 | wool_block_id = 35 814 | wool_block_data = 1 #orange 815 | 816 | turtle.penblock(wool_block_id, wool_block_data) 817 | turtle.right(10) 818 | 819 | ``` 820 | 821 |
822 | 823 |
824 | 825 | turtle.penup() 826 | 827 | 828 | > Put the pen up (stop drawing when the turtle moves) 829 | 830 | ```python 831 | 832 | from mcpi import minecraft 833 | from minecraftstuff import MinecraftTurtle 834 | 835 | #Connect to minecraft server 127.0.0.1 as player 'steve' 836 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 837 | 838 | #Get current player's position 839 | pos = mc.player.getPos() 840 | 841 | 842 | # create minecraft turtle 843 | turtle = MinecraftTurtle(mc, pos) 844 | 845 | turtle.down(10) 846 | 847 | turtle.penup() 848 | 849 | turtle.right(10) 850 | 851 | ``` 852 | 853 |
854 | 855 |
856 | 857 | turtle.pendown() 858 | 859 | 860 | > Put the pen down (start drawing again when the turtle moves after you called turtle.penup()) 861 | 862 | ```python 863 | 864 | from mcpi import minecraft 865 | from minecraftstuff import MinecraftTurtle 866 | 867 | #Connect to minecraft server 127.0.0.1 as player 'steve' 868 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 869 | 870 | #Get current player's position 871 | pos = mc.player.getPos() 872 | 873 | 874 | # create minecraft turtle 875 | turtle = MinecraftTurtle(mc, pos) 876 | 877 | turtle.down(10) 878 | 879 | turtle.pendown() 880 | 881 | turtle.right(10) 882 | 883 | turtle.penup() 884 | 885 | turtle.up(10) 886 | 887 | ``` 888 | 889 |
890 | 891 |
892 | 893 | turtle.isdown() 894 | 895 | 896 | > Check if the pen is down, returning a boolean 897 | 898 | ```python 899 | 900 | from mcpi import minecraft 901 | from minecraftstuff import MinecraftTurtle 902 | 903 | #Connect to minecraft server 127.0.0.1 as player 'steve' 904 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 905 | 906 | #Get current player's position 907 | pos = mc.player.getPos() 908 | 909 | 910 | # create minecraft turtle 911 | turtle = MinecraftTurtle(mc, pos) 912 | 913 | turtle.down(10) 914 | 915 | turtle.pendown() 916 | 917 | turtle.right(10) 918 | 919 | if turtle.isdown(): 920 | print "Pen is down!" 921 | 922 | ``` 923 | 924 |
925 | 926 | 927 |
928 | 929 | turtle.setposition(x, y, z) 930 | 931 | 932 | > Reset turtle's position to a given x/y/z coordinate 933 | 934 | ```python 935 | 936 | from mcpi import minecraft 937 | from minecraftstuff import MinecraftTurtle 938 | 939 | #Connect to minecraft server 127.0.0.1 as player 'steve' 940 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 941 | 942 | #Get current player's position 943 | pos = mc.player.getPos() 944 | 945 | 946 | # create minecraft turtle at player's current position 947 | turtle = MinecraftTurtle(mc, pos) 948 | 949 | turtle.down(10) 950 | 951 | turtle.right(10) 952 | 953 | # Have turtle reset back to player's position 954 | turtle.setposition(pos.x, pos.y, pos.z) 955 | 956 | ``` 957 | 958 |
959 | 960 |
961 | 962 | turtle.setx(x) 963 | 964 | 965 | > Reset turtle's position to a given x coordinate 966 | 967 | ```python 968 | 969 | from mcpi import minecraft 970 | from minecraftstuff import MinecraftTurtle 971 | 972 | #Connect to minecraft server 127.0.0.1 as player 'steve' 973 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 974 | 975 | #Get current player's position 976 | pos = mc.player.getPos() 977 | 978 | 979 | # create minecraft turtle at player's current position 980 | turtle = MinecraftTurtle(mc, pos) 981 | 982 | turtle.down(10) 983 | 984 | turtle.right(10) 985 | 986 | # Have turtle reset back to player's x position 987 | turtle.setx(pos.x) 988 | 989 | ``` 990 | 991 |
992 | 993 |
994 | 995 | turtle.sety(y) 996 | 997 | 998 | > Reset turtle's position to a given y coordinate 999 | 1000 | ```python 1001 | 1002 | from mcpi import minecraft 1003 | from minecraftstuff import MinecraftTurtle 1004 | 1005 | #Connect to minecraft server 127.0.0.1 as player 'steve' 1006 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 1007 | 1008 | #Get current player's position 1009 | pos = mc.player.getPos() 1010 | 1011 | 1012 | # create minecraft turtle at player's current position 1013 | turtle = MinecraftTurtle(mc, pos) 1014 | 1015 | turtle.down(10) 1016 | 1017 | turtle.right(10) 1018 | 1019 | # Have turtle reset back to player's y position 1020 | turtle.setx(pos.y) 1021 | 1022 | ``` 1023 | 1024 |
1025 | 1026 |
1027 | 1028 | turtle.setz(z) 1029 | 1030 | 1031 | > Reset turtle's position to a given z coordinate 1032 | 1033 | ```python 1034 | 1035 | from mcpi import minecraft 1036 | from minecraftstuff import MinecraftTurtle 1037 | 1038 | #Connect to minecraft server 127.0.0.1 as player 'steve' 1039 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 1040 | 1041 | #Get current player's position 1042 | pos = mc.player.getPos() 1043 | 1044 | 1045 | # create minecraft turtle at player's current position 1046 | turtle = MinecraftTurtle(mc, pos) 1047 | 1048 | turtle.down(10) 1049 | 1050 | turtle.right(10) 1051 | 1052 | # Have turtle reset back to player's z position 1053 | turtle.setx(pos.z) 1054 | 1055 | ``` 1056 | 1057 |
1058 | 1059 |
1060 | 1061 | turtle.position 1062 | 1063 | 1064 | > Retrieve turtle's current x/y/z position 1065 | 1066 | ```python 1067 | 1068 | from mcpi import minecraft 1069 | from minecraftstuff import MinecraftTurtle 1070 | 1071 | #Connect to minecraft server 127.0.0.1 as player 'steve' 1072 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 1073 | 1074 | #Get current player's position 1075 | pos = mc.player.getPos() 1076 | 1077 | 1078 | # create minecraft turtle at player's current position 1079 | turtle = MinecraftTurtle(mc, pos) 1080 | 1081 | turtlePos = turtle.position 1082 | print turtlePos.x 1083 | print turtlePos.y 1084 | print turtlePos.z 1085 | 1086 | 1087 | ``` 1088 | 1089 |
1090 | 1091 |
1092 | 1093 | turtle.setheading(angle) 1094 | 1095 | 1096 | > Set the turtles headings 1097 | 1098 | ```python 1099 | 1100 | from mcpi import minecraft 1101 | from minecraftstuff import MinecraftTurtle 1102 | 1103 | #Connect to minecraft server 127.0.0.1 as player 'steve' 1104 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 1105 | 1106 | #Get current player's position 1107 | pos = mc.player.getPos() 1108 | 1109 | 1110 | # create minecraft turtle at player's current position 1111 | turtle = MinecraftTurtle(mc, pos) 1112 | 1113 | turtle.setheading(90) 1114 | 1115 | ``` 1116 | 1117 |
1118 | 1119 | 1120 |
1121 | 1122 | turtle.setverticalheading(angle) 1123 | 1124 | 1125 | > Set the turtles vertical headings 1126 | 1127 | ```python 1128 | 1129 | from mcpi import minecraft 1130 | from minecraftstuff import MinecraftTurtle 1131 | 1132 | #Connect to minecraft server 127.0.0.1 as player 'steve' 1133 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 1134 | 1135 | #Get current player's position 1136 | pos = mc.player.getPos() 1137 | 1138 | 1139 | # create minecraft turtle at player's current position 1140 | turtle = MinecraftTurtle(mc, pos) 1141 | 1142 | turtle.setverticalheading(90) 1143 | 1144 | ``` 1145 | 1146 |
1147 | 1148 |
1149 | 1150 | turtle.walk() 1151 | 1152 | 1153 | > Force the turtle to walk along the ground 1154 | 1155 | ```python 1156 | 1157 | from mcpi import minecraft 1158 | from minecraftstuff import MinecraftTurtle 1159 | 1160 | #Connect to minecraft server 127.0.0.1 as player 'steve' 1161 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 1162 | 1163 | #Get current player's position 1164 | pos = mc.player.getPos() 1165 | 1166 | 1167 | # create minecraft turtle at player's current position 1168 | turtle = MinecraftTurtle(mc, pos) 1169 | 1170 | turtle.walk() 1171 | 1172 | ``` 1173 | 1174 |
1175 | 1176 |
1177 | 1178 | turtle.fly() 1179 | 1180 | 1181 | > Allow the turtle to fly (e.g. not be forced to move along the ground) 1182 | 1183 | ```python 1184 | 1185 | from mcpi import minecraft 1186 | from minecraftstuff import MinecraftTurtle 1187 | 1188 | #Connect to minecraft server 127.0.0.1 as player 'steve' 1189 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 1190 | 1191 | #Get current player's position 1192 | pos = mc.player.getPos() 1193 | 1194 | 1195 | # create minecraft turtle at player's current position 1196 | turtle = MinecraftTurtle(mc, pos) 1197 | 1198 | turtle.fly() 1199 | 1200 | ``` 1201 | 1202 |
1203 | 1204 | #### minecraftstuff.MinecraftShape 1205 | 1206 | - Official Documentation 1207 | 1208 | #### minecraftstuff.MinecraftDrawing 1209 | 1210 | - Official Documentation 1211 | 1212 | ## Block IDs 1213 | 1214 | - Website with lookup table 1215 | - Using a python library [Scroll down to 'Blocks' section] -------------------------------------------------------------------------------- /examples/mcpi_import_3d_model.py: -------------------------------------------------------------------------------- 1 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 2 | import os.path, sys 3 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 4 | 5 | #Example Source from: https://github.com/martinohanlon/minecraft-renderObjv2 6 | 7 | #from minecraftstuff import MinecraftDrawing 8 | import mcpi.minecraft as minecraft 9 | import mcpi.block as block 10 | import time 11 | import datetime 12 | 13 | # class to create 3d filled polygons 14 | class MinecraftDrawing: 15 | def __init__(self, mc): 16 | self.mc = mc 17 | 18 | # draw point 19 | def drawPoint3d(self, x, y, z, blockType, blockData=None): 20 | self.mc.setBlock(x,y,z,blockType,blockData) 21 | #print("x = " + str(x) + ", y = " + str(y) + ", z = " + str(z)) 22 | 23 | # draws a face, when passed a collection of vertices which make up a polyhedron 24 | def drawFace(self, vertices, blockType, blockData=None): 25 | 26 | # get the edges of the face 27 | edgesVertices = [] 28 | # persist first vertex 29 | firstVertex = vertices[0] 30 | # loop through vertices and get edges 31 | vertexCount = 0 32 | for vertex in vertices: 33 | vertexCount+=1 34 | if vertexCount > 1: 35 | # got 2 vertices, get the points for the edge 36 | edgesVertices = edgesVertices + self.getLine(lastVertex.x, lastVertex.y, lastVertex.z, vertex.x, vertex.y, vertex.z) 37 | #print("x = " + str(lastVertex.x) + ", y = " + str(lastVertex.y) + ", z = " + str(lastVertex.z) + " x2 = " + str(vertex.x) + ", y2 = " + str(vertex.y) + ", z2 = " + str(vertex.z)) 38 | # persist the last vertex found 39 | lastVertex = vertex 40 | # get edge between the last and first vertices 41 | edgesVertices = edgesVertices + self.getLine(lastVertex.x, lastVertex.y, lastVertex.z, firstVertex.x, firstVertex.y, firstVertex.z) 42 | 43 | # sort edges vertices 44 | def keyX( point ): return point.x 45 | def keyY( point ): return point.y 46 | def keyZ( point ): return point.z 47 | edgesVertices.sort( key=keyZ ) 48 | edgesVertices.sort( key=keyY ) 49 | edgesVertices.sort( key=keyX ) 50 | 51 | # not very performant but wont have gaps between in complex models 52 | for vertex in edgesVertices: 53 | vertexCount+=1 54 | # got 2 vertices, draw lines between them 55 | if (vertexCount > 1): 56 | self.drawLine(lastVertex.x, lastVertex.y, lastVertex.z, vertex.x, vertex.y, vertex.z, blockType, blockData) 57 | #print("x = " + str(lastVertex.x) + ", y = " + str(lastVertex.y) + ", z = " + str(lastVertex.z) + " x2 = " + str(vertex.x) + ", y2 = " + str(vertex.y) + ", z2 = " + str(vertex.z)) 58 | # persist the last vertex found 59 | lastVertex = vertex 60 | 61 | # draw's all the points in a collection of vertices with a block 62 | def drawVertices(self, vertices, blockType, blockData=None): 63 | for vertex in vertices: 64 | self.drawPoint3d(vertex.x, vertex.y, vertex.z, blockType, blockData) 65 | 66 | # draw line 67 | def drawLine(self, x1, y1, z1, x2, y2, z2, blockType, blockData): 68 | self.drawVertices(self.getLine(x1, y1, z1, x2, y2, z2), blockType, blockData) 69 | 70 | # returns points on a line 71 | def getLine(self, x1, y1, z1, x2, y2, z2): 72 | 73 | # return maximum of 2 values 74 | def MAX(a,b): 75 | if a > b: return a 76 | else: return b 77 | 78 | # return step 79 | def ZSGN(a): 80 | if a < 0: return -1 81 | elif a > 0: return 1 82 | elif a == 0: return 0 83 | 84 | # list for vertices 85 | vertices = [] 86 | 87 | # if the 2 points are the same, return single vertice 88 | if (x1 == x2 and y1 == y2 and z1 == z2): 89 | vertices.append(minecraft.Vec3(x1, y1, z1)) 90 | 91 | # else get all points in edge 92 | else: 93 | 94 | dx = x2 - x1 95 | dy = y2 - y1 96 | dz = z2 - z1 97 | 98 | ax = abs(dx) << 1 99 | ay = abs(dy) << 1 100 | az = abs(dz) << 1 101 | 102 | sx = ZSGN(dx) 103 | sy = ZSGN(dy) 104 | sz = ZSGN(dz) 105 | 106 | x = x1 107 | y = y1 108 | z = z1 109 | 110 | # x dominant 111 | if (ax >= MAX(ay, az)): 112 | yd = ay - (ax >> 1) 113 | zd = az - (ax >> 1) 114 | loop = True 115 | while(loop): 116 | vertices.append(minecraft.Vec3(x, y, z)) 117 | if (x == x2): 118 | loop = False 119 | if (yd >= 0): 120 | y += sy 121 | yd -= ax 122 | if (zd >= 0): 123 | z += sz 124 | zd -= ax 125 | x += sx 126 | yd += ay 127 | zd += az 128 | # y dominant 129 | elif (ay >= MAX(ax, az)): 130 | xd = ax - (ay >> 1) 131 | zd = az - (ay >> 1) 132 | loop = True 133 | while(loop): 134 | vertices.append(minecraft.Vec3(x, y, z)) 135 | if (y == y2): 136 | loop=False 137 | if (xd >= 0): 138 | x += sx 139 | xd -= ay 140 | if (zd >= 0): 141 | z += sz 142 | zd -= ay 143 | y += sy 144 | xd += ax 145 | zd += az 146 | # z dominant 147 | elif(az >= MAX(ax, ay)): 148 | xd = ax - (az >> 1) 149 | yd = ay - (az >> 1) 150 | loop = True 151 | while(loop): 152 | vertices.append(minecraft.Vec3(x, y, z)) 153 | if (z == z2): 154 | loop=False 155 | if (xd >= 0): 156 | x += sx 157 | xd -= az 158 | if (yd >= 0): 159 | y += sy 160 | yd -= az 161 | z += sz 162 | xd += ax 163 | yd += ay 164 | 165 | return vertices 166 | 167 | def load_obj(filename, defaultBlock, materials) : 168 | V = [] #vertex 169 | T = [] #texcoords 170 | N = [] #normals 171 | F = [] #face indexies 172 | MF = [] #materials to faces 173 | 174 | currentMaterial = defaultBlock 175 | 176 | fh = open(filename) 177 | for line in fh : 178 | if line[0] == '#' : continue 179 | line = line.strip().split(' ') 180 | if line[0] == 'v' : #vertex 181 | V.append(line[1:]) 182 | elif line[0] == 'vt' : #tex-coord 183 | T.append(line[1:]) 184 | elif line[0] == 'vn' : #normal vector 185 | N.append(line[1:]) 186 | elif line[0] == 'f' : #face 187 | face = line[1:] 188 | for i in range(0, len(face)) : 189 | face[i] = face[i].split('/') 190 | # OBJ indexies are 1 based not 0 based hence the -1 191 | # convert indexies to integer 192 | for j in range(0, len(face[i])) : 193 | if face[i][j] != "": 194 | face[i][j] = int(face[i][j]) - 1 195 | #append the material currently in use to the face 196 | F.append(face) 197 | MF.append(currentMaterial) 198 | 199 | elif line[0] == 'usemtl': # material 200 | 201 | usemtl = line[1] 202 | if (usemtl in materials.keys()): 203 | currentMaterial = materials[usemtl] 204 | else: 205 | currentMaterial = defaultBlock 206 | print("Warning: Couldn't find '" + str(usemtl) + "' in materials using default") 207 | 208 | return V, T, N, F, MF 209 | 210 | # strips the x,y,z co-ords from a vertex line, scales appropriately, rounds and converts to int 211 | def getVertexXYZ(vertexLine, scale, startCoord, swapYZ): 212 | # convert, round and scale 213 | x = int((float(vertexLine[0]) * scale) + 0.5) 214 | y = int((float(vertexLine[1]) * scale) + 0.5) 215 | z = int((float(vertexLine[2]) * scale) + 0.5) 216 | # add startCoord to x,y,z 217 | x = x + startCoord.x 218 | y = y + startCoord.y 219 | z = z + startCoord.z 220 | # swap y and z coord if needed 221 | if swapYZ == True: 222 | swap = y 223 | y = z 224 | z = swap 225 | return x, y, z 226 | 227 | # main program 228 | if __name__ == "__main__": 229 | 230 | print(datetime.datetime.now()) 231 | 232 | # Connect to minecraft server 127.0.0.1 as player 'steve' 233 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 234 | 235 | #Create minecraft drawing class 236 | mcDrawing = MinecraftDrawing(mc) 237 | 238 | """ 239 | Load objfile and set constants 240 | 241 | COORDSSCALE = factor to scale the co-ords by 242 | STARTCOORD = where to start the model, the relative position 0 243 | CLEARAREA1/2 = 2 points the program should clear an area in between to put the model in 244 | SWAPYZ = True to sway the Y and Z dimension 245 | MATERIALS = a dictionary object which maps materials in the obj file to blocks in minecraft 246 | DEFAULTBLOCK = the default type of block to build the model in, used if a material cant be found 247 | """ 248 | 249 | what_to_build = "shuttle" #Valid values: shuttle, skyscraper, or farmhouse 250 | 251 | if what_to_build == "shuttle": 252 | COORDSSCALE = 6 253 | 254 | #Build model 20 blocks above player 255 | pos = mc.player.getTilePos() 256 | STARTCOORD = minecraft.Vec3(pos.x,pos.z,pos.y+20) 257 | SWAPYZ = True 258 | #Note: Y and Z are swapped in this 3d model compared to the MC universe 259 | 260 | DEFAULTBLOCK = [block.WOOL.id,0] 261 | MATERIALS = {"glass": [block.GLASS.id, 0], 262 | "bone": [block.WOOL.id, 0], 263 | "fldkdkgrey": [block.WOOL.id, 7], 264 | "redbrick": [block.WOOL.id, 14], 265 | "black": [block.WOOL.id, 15], 266 | "brass": [block.WOOL.id, 1], 267 | "dkdkgrey": [block.WOOL.id, 7]} 268 | vertices,textures,normals,faces,materials = load_obj("resources/shuttle.obj", DEFAULTBLOCK, MATERIALS) 269 | 270 | if what_to_build == "skyscraper": 271 | COORDSSCALE = 1.4 272 | #Build model 20 blocks to size of player 273 | pos = mc.player.getTilePos() 274 | STARTCOORD = minecraft.Vec3(pos.x,pos.y,pos.z+20) 275 | SWAPYZ = False 276 | DEFAULTBLOCK = [block.IRON_BLOCK, 0] 277 | MATERIALS = {"glass": [block.GLASS.id, 0], 278 | "bone": [block.WOOL.id, 0], 279 | "fldkdkgrey": [block.WOOL.id, 7], 280 | "redbrick": [block.WOOL.id, 14], 281 | "black": [block.WOOL.id, 15], 282 | "brass": [block.WOOL.id, 1], 283 | "dkdkgrey": [block.WOOL.id, 7]} 284 | 285 | MATERIALS = { 286 | "brass": [block.WOOL.id, 1], 287 | "bone": [block.WOOL.id, 0], 288 | "black": [block.WOOL.id, 15], 289 | "bluteal": [block.IRON_BLOCK, 0], 290 | "tan": [24, 2], 291 | "blutan": [42, 0], 292 | "brown": [5, 1], 293 | "ltbrown": [5, 3], 294 | } 295 | 296 | vertices,textures,normals,faces,materials = load_obj("resources/skyscraper.obj", DEFAULTBLOCK, MATERIALS) 297 | 298 | if what_to_build == "farmhouse": 299 | COORDSSCALE = 1 300 | #Build model 20 blocks to size of player 301 | pos = mc.player.getTilePos() 302 | STARTCOORD = minecraft.Vec3(pos.x,pos.y,pos.z+20) 303 | DEFAULTBLOCK = [block.IRON_BLOCK, 0] 304 | MATERIALS = {} 305 | SWAPYZ = False 306 | vertices,textures,normals,faces,materials = load_obj("resources/farmhouse.obj", DEFAULTBLOCK, MATERIALS) 307 | 308 | print("obj file loaded") 309 | 310 | #Post a message to the minecraft chat window 311 | mc.postToChat("Started 3d render...") 312 | 313 | faceCount = 0 314 | # loop through faces 315 | for face in faces: 316 | faceVertices = [] 317 | 318 | # loop through vertex's in face and call drawFace function 319 | for vertex in face: 320 | #strip co-ords from vertex line 321 | vertexX, vertexY, vertexZ = getVertexXYZ(vertices[vertex[0]], COORDSSCALE, STARTCOORD, SWAPYZ) 322 | 323 | faceVertices.append(minecraft.Vec3(vertexX,vertexY,vertexZ)) 324 | 325 | # draw the face 326 | mcDrawing.drawFace(faceVertices, materials[faceCount][0], materials[faceCount][1]) 327 | faceCount = faceCount + 1 328 | 329 | mc.postToChat("Model complete.") 330 | 331 | print(datetime.datetime.now()) 332 | -------------------------------------------------------------------------------- /examples/mcpi_pixel_art.py: -------------------------------------------------------------------------------- 1 | """ 2 | This script does the following: 3 | - Take an image as input, and read it pixel by pixel. 4 | - For each pixel in the image, set a block in the minecraft world closest to the color of that pixel. 5 | - End result should be pixel art in minecraft world. 6 | - Use resources/mario.gif in this directory to start with. 7 | 8 | NOTE! This script requires installing the Python library 'pillow' - instructions located here: 9 | https://pillow.readthedocs.org/en/latest/installation.html 10 | """ 11 | 12 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 13 | import os.path, sys 14 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 15 | 16 | import mcpi.minecraft as minecraft 17 | from math import sqrt 18 | from PIL import Image 19 | 20 | # Connect to minecraft server 127.0.0.1 as player 'steve' 21 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 22 | 23 | 24 | # Possible blocks in (Name, ID, (RGB1,RGB2,..),Data) 25 | #RGBs are used to color match. 26 | possibleBlocks = ( 27 | ("Air", 0, ( (0, 136, 255) ,),0), 28 | ("Smooth Stone", 1, ( (125,125, 125) ,),0), 29 | ("Dirt", 3, ( (133,96,66),),0), 30 | ("Cobblestone", 4, ( (117,117,117),),0), 31 | ("Wooden Plank", 5, ( (156,127,78),),0), 32 | ("Bedrock", 7, ( (83,83,83),),0), 33 | ("Sand", 12, ( (217,210,158),),0), 34 | ("Gravel", 13, ( (136, 126, 125),),0), 35 | ("Gold Ore", 14, ( (143,139,124),),0), 36 | ("Iron Ore", 15, ( (135,130,126),),0), 37 | ("Coal Ore", 16, ( (115,115,115),),0), 38 | ("Wood", 17, ( (154,125,77),),0), 39 | ("Sponge", 19, ( (182,182,57),),0), 40 | ("White Wool", 35, ( (221,221,221),),0), 41 | ("Orange Wool", 35, ( (233,126,55),),1), 42 | ("Magenta Wool", 35, ( (179,75,200),),2), 43 | ("Light Blue Wool", 35, ( (103,137,211),),3), 44 | ("Yellow Wool", 35, ( (192,179,28),),4), 45 | ("Light Green Wool", 35, ( (59,187,47),),5), 46 | ("Pink Wool", 35, ( (217,132,153),),6), 47 | ("Dark Gray Wool", 35, ( (66,67,67),),7), 48 | ("Gray Wool", 35, ( (157,164,165),),8), 49 | ("Cyan Wool", 35, ( (39,116,148),),9), 50 | ("Purple Wool", 35, ( (128,53,195),),10), 51 | ("Blue Wool", 35, ( (39,51,153),),11), 52 | ("Brown Wool", 35, ( (85,51,27),),12), 53 | ("Dark Green Wool", 35, ( (55,76,24),),13), 54 | ("Red Wool", 35, ( (162,44,42),),14), 55 | ("Black Wool", 35, ( (26,23,23),),15), 56 | ("Gold", 41, ( (249,236,77),),0), 57 | ("Iron", 42, ( (230,230,230),),0), 58 | ("TwoHalves", 43, ( (159,159,159),),0), 59 | ("Brick", 45, ( (155,110,97),),0), 60 | ("Mossy Cobblestone", 48, ( (90,108,90),),0), 61 | ("Obsidian", 49, ( (20,18,29),),0), 62 | ("Diamond Ore", 56, ( (129,140,143),),0), 63 | ("Diamond Block", 57, ( (99,219,213),),0), 64 | ("Workbench", 58, ( (107,71,42),),0), 65 | ("Redstone Ore", 73, ( (132,107,107),),0), 66 | ("Snow Block", 80, ( (239,251,251),),0), 67 | ("Clay", 82, ( (158,164,176),),0), 68 | ("Jukebox", 84, ( (107,73,55),),0), 69 | ("Pumpkin", 86, ( (192,118,21),),0), 70 | ("Netherrack", 87, ( (110,53,51),),0), 71 | ("Soul Sand", 88, ( (84,64,51),),0), 72 | ("Glowstone", 89, ( (137,112,64),),0) 73 | ) 74 | 75 | def getBlockFromColor(RGB): 76 | smallestDistIndex = -1 77 | smallestDist = 300000 78 | curIndex = 0 79 | for block in possibleBlocks: 80 | for blockRGB in block[2]: 81 | curDist = getColorDist(RGB, blockRGB) 82 | 83 | if (curDist < smallestDist): 84 | smallestDist = curDist 85 | smallestDistIndex = curIndex 86 | 87 | curIndex = curIndex + 1 88 | 89 | if (smallestDistIndex == -1): 90 | return -1 91 | 92 | return possibleBlocks[smallestDistIndex] 93 | 94 | def getColorDist(colorRGB, blockRGB): 95 | return sqrt( pow(colorRGB[0]-blockRGB[0],2) + pow(colorRGB[1]-blockRGB[1],2) + pow(colorRGB[2]-blockRGB[2],2)) 96 | 97 | pos = mc.player.getPos() 98 | 99 | maxsize = (100, 100) 100 | 101 | im = Image.open('resources/mario.gif') 102 | im.thumbnail(maxsize, Image.ANTIALIAS) 103 | rgb_im = im.convert('RGB') 104 | rows, columns = rgb_im.size 105 | for r in range(rows): 106 | for c in range(columns): 107 | rgb = rgb_im.getpixel((r, c)) 108 | mc_block = getBlockFromColor(rgb) 109 | mc.setBlock(pos.x+r, pos.y, pos.z+c, mc_block[1]) 110 | -------------------------------------------------------------------------------- /examples/mcpi_pyramid_algorithm.py: -------------------------------------------------------------------------------- 1 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 2 | import os.path, sys 3 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 4 | 5 | import mcpi.minecraft as minecraft 6 | 7 | # Connect to minecraft server 127.0.0.1 as player 'steve' 8 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 9 | 10 | block_id = 57 11 | 12 | pos = mc.player.getPos() 13 | 14 | pyramid_height = 10 15 | 16 | for i in range(pyramid_height): 17 | x = pos.x + i 18 | y = pos.y + i 19 | z = pos.z + i 20 | 21 | x2 = x + (pyramid_height*2) - 2 - (i*2) 22 | y2 = y 23 | z2 = z + (pyramid_height*2) - 2 - (i*2) 24 | mc.setBlocks(x, y, z, x2, y2, z2, block_id) 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/mcpi_superpowers.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file gives you super powers in game! 3 | 4 | They can be activated by: 5 | - right clicking a block with a sword 6 | - shooting an arrow 7 | - typing specific messages into chat 8 | 9 | """ 10 | 11 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 12 | import os.path, sys 13 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 14 | 15 | import mcpi.minecraft as minecraft 16 | import time 17 | 18 | # Connect to minecraft server 127.0.0.1 as player 'steve' 19 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 20 | 21 | while True: 22 | 23 | for blockhit in mc.player.pollProjectileHits(): 24 | # When I shoot an arrow, teleport me to where the arrow lands 25 | pos = blockhit.pos 26 | mc.player.setPos(pos.x, pos.y, pos.z) 27 | 28 | 29 | for blockhit in mc.player.pollBlockHits(): 30 | # When I right click a block with my sword, clear out space 31 | pos = blockhit.pos 32 | mc.setBlocks(pos.x+2, pos.y+2, pos.z+2, pos.x-2, pos.y-2, pos.z-2, 0) 33 | 34 | for chatpost in mc.player.pollChatPosts(): 35 | 36 | if chatpost.message.lower() == "shield": 37 | # Surround myself in bedrock. After 4 seconds, change it to glass. 38 | mc.postToChat("Shield activated!") 39 | pos = mc.player.getTilePos() 40 | mc.player.setPos(pos.x, pos.y, pos.z) #Put player on center of block 41 | x = pos.x-1 42 | y = pos.y-1 43 | z = pos.z-1 44 | 45 | x2 = x + 2 46 | y2 = y + 3 47 | z2 = z + 2 48 | 49 | bedrock_block_id = 7 50 | mc.setBlocks(x, y, z, x2, y2, z2, bedrock_block_id) 51 | 52 | air_block_id = 0 53 | mc.setBlocks(x+1, y+1, z+1, x2-1, y2-1, z2-1, air_block_id) 54 | 55 | time.sleep(4) 56 | 57 | bedrock_block_id = 20 58 | mc.setBlocks(x, y, z, x2, y2, z2, bedrock_block_id) 59 | 60 | air_block_id = 0 61 | mc.setBlocks(x+1, y+1, z+1, x2-1, y2-1, z2-1, air_block_id) 62 | 63 | elif chatpost.message.lower() == "imonfire": 64 | # Pour water over me, then replace water with air to cleanup after self. 65 | mc.postToChat("Pouring water over you!") 66 | 67 | pos = mc.player.getPos() 68 | water_block_id = 8 69 | mc.setBlock(pos.x, pos.y+3, pos.z, water_block_id) 70 | 71 | time.sleep(3) 72 | 73 | air_block_id = 0 74 | mc.setBlock(pos.x, pos.y+3, pos.z, air_block_id) 75 | 76 | time.sleep(.1) 77 | -------------------------------------------------------------------------------- /examples/minecraftstuff_drawing.py: -------------------------------------------------------------------------------- 1 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 2 | import os.path, sys 3 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 4 | 5 | from minecraftstuff import MinecraftDrawing, ShapeBlock, Points 6 | import mcpi.minecraft as minecraft 7 | import mcpi.block as block 8 | 9 | # Connect to minecraft server 127.0.0.1 as player 'steve' 10 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 11 | 12 | mc.player.setPos(-25, 0, -25) 13 | 14 | #clear area 15 | mc.setBlocks(-25, 0, -25, 25, 25, 25, block.AIR.id) 16 | 17 | #create drawing object 18 | mcDrawing = MinecraftDrawing(mc) 19 | 20 | #line 21 | mcDrawing.drawLine(0,0,-10,-10,10,-5,block.STONE.id) 22 | 23 | #circle 24 | mcDrawing.drawCircle(-15,15,-15,10,block.WOOD.id) 25 | 26 | #sphere 27 | mcDrawing.drawSphere(-15,15,-15,5,block.OBSIDIAN.id) 28 | 29 | #face - solid triangle 30 | faceVertices = [] 31 | faceVertices.append(minecraft.Vec3(0,0,0)) 32 | faceVertices.append(minecraft.Vec3(5,10,0)) 33 | faceVertices.append(minecraft.Vec3(10,0,0)) 34 | mcDrawing.drawFace(faceVertices, True, block.SNOW_BLOCK.id) 35 | 36 | #face - wireframe square - using Points 37 | faceVertices = Points() 38 | faceVertices.add(0,0,5) 39 | faceVertices.add(10,0,5) 40 | faceVertices.add(10,10,5) 41 | faceVertices.add(0,10,5) 42 | mcDrawing.drawFace(faceVertices, False, block.DIAMOND_BLOCK.id) 43 | 44 | #face - 5 sided shape 45 | faceVertices = [] 46 | faceVertices.append(minecraft.Vec3(0,15,0)) 47 | faceVertices.append(minecraft.Vec3(5,15,5)) 48 | faceVertices.append(minecraft.Vec3(3,15,10)) 49 | faceVertices.append(minecraft.Vec3(-3,15,10)) 50 | faceVertices.append(minecraft.Vec3(-5,15,5)) 51 | mcDrawing.drawFace(faceVertices, True, block.GOLD_BLOCK.id) -------------------------------------------------------------------------------- /examples/minecraftstuff_shapes.py: -------------------------------------------------------------------------------- 1 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 2 | import os.path, sys 3 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 4 | 5 | from minecraftstuff import MinecraftShape, ShapeBlock 6 | import mcpi.minecraft as minecraft 7 | import mcpi.block as block 8 | import time 9 | 10 | # Connect to minecraft server 127.0.0.1 as player 'steve' 11 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 12 | 13 | #test MinecraftShape 14 | playerPos = mc.player.getTilePos() 15 | 16 | #create the shape object 17 | shapeBlocks = [ShapeBlock(0,0,0,block.DIAMOND_BLOCK.id), 18 | ShapeBlock(1,0,0,block.DIAMOND_BLOCK.id), 19 | ShapeBlock(1,0,1,block.DIAMOND_BLOCK.id), 20 | ShapeBlock(0,0,1,block.DIAMOND_BLOCK.id), 21 | ShapeBlock(0,1,0,block.DIAMOND_BLOCK.id), 22 | ShapeBlock(1,1,0,block.DIAMOND_BLOCK.id), 23 | ShapeBlock(1,1,1,block.DIAMOND_BLOCK.id), 24 | ShapeBlock(0,1,1,block.DIAMOND_BLOCK.id)] 25 | 26 | #move the shape about 27 | myShape = MinecraftShape(mc, playerPos, shapeBlocks) 28 | print("drawn shape") 29 | time.sleep(10) 30 | myShape.moveBy(-1,1,-1) 31 | time.sleep(1) 32 | myShape.moveBy(1,0,1) 33 | time.sleep(1) 34 | myShape.moveBy(1,1,0) 35 | time.sleep(1) 36 | 37 | #rotate the shape 38 | myShape.rotate(90,0,0) 39 | 40 | #clear the shape 41 | myShape.clear() -------------------------------------------------------------------------------- /examples/minecraftstuff_shapes_rotation.py: -------------------------------------------------------------------------------- 1 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 2 | import os.path, sys 3 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 4 | 5 | from minecraftstuff import MinecraftShape 6 | import mcpi.minecraft as minecraft 7 | import mcpi.block as block 8 | import time 9 | 10 | # Connect to minecraft server 127.0.0.1 as player 'steve' 11 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 12 | 13 | #test shape 14 | pos = mc.player.getTilePos() 15 | pos.y += 40 16 | 17 | myShape = MinecraftShape(mc, pos) 18 | try: 19 | print("draw shape") 20 | myShape.setBlocks(-5, 0, -5, 3, 0, 3, block.WOOL.id, 5) 21 | print("draw shape done") 22 | 23 | time.sleep(5) 24 | roll = 0 25 | pitch = 0 26 | yaw = 0 27 | 28 | #angles = [15,30,45,60,75,90] 29 | angles = [45, 90] 30 | 31 | print("roll shape") 32 | for roll in angles: 33 | myShape.rotate(yaw, pitch, roll) 34 | print("roll shape {} done".format(roll)) 35 | time.sleep(1) 36 | 37 | for pitch in angles: 38 | myShape.rotate(yaw, pitch, roll) 39 | time.sleep(1) 40 | 41 | for yaw in angles: 42 | myShape.rotate(yaw, pitch, roll) 43 | time.sleep(1) 44 | 45 | for count in range(0,5): 46 | myShape.moveBy(1,0,0) 47 | time.sleep(0.5) 48 | 49 | time.sleep(5) 50 | finally: 51 | myShape.clear() 52 | -------------------------------------------------------------------------------- /examples/resources/farmhouse.obj: -------------------------------------------------------------------------------- 1 | # This file uses centimeters as units for non-parametric coordinates. 2 | 3 | mtllib Farmhouse OBJ.mtl 4 | g default 5 | v -2.023838 8.915440 -8.054992 6 | v 1.971210 8.917807 -8.054984 7 | v 1.971237 1.352654 -8.054985 8 | v -1.992085 1.352654 -8.054985 9 | v 1.821583 8.753086 29.128180 10 | v 7.079507 8.753086 29.128180 11 | v 1.821583 8.907376 29.172422 12 | v 7.079507 8.907376 29.172422 13 | v 1.821583 9.398357 27.460169 14 | v 7.079507 9.398357 27.460169 15 | v 1.821583 9.244067 27.415926 16 | v 7.079507 9.244067 27.415926 17 | v 2.041729 8.753086 29.128180 18 | v 2.041729 8.907376 29.172422 19 | v 2.041729 9.398357 27.460169 20 | v 2.041729 9.244067 27.415926 21 | v 6.864059 8.753086 29.128180 22 | v 6.864059 8.907376 29.172422 23 | v 6.864059 9.398357 27.460169 24 | v 6.864059 9.244067 27.415926 25 | v 1.821583 8.440932 27.439030 26 | v 2.041729 8.440932 27.439030 27 | v 2.041729 8.613385 28.897882 28 | v 1.821583 8.613385 28.897882 29 | v 6.864059 8.440932 27.439034 30 | v 6.864058 8.613384 28.897886 31 | v 7.079507 8.440932 27.439034 32 | v 7.079506 8.613384 28.897886 33 | v 6.757504 8.950987 27.234821 34 | v 2.229405 8.950924 27.234819 35 | v 2.209645 0.083778 27.234821 36 | v 6.801266 0.083778 27.234825 37 | v 9.584381 0.083779 27.468933 38 | v -9.562160 0.083779 27.468933 39 | v -9.562160 0.083778 -8.258186 40 | v 9.584381 0.083778 -8.258186 41 | v 9.584381 1.352654 -8.258186 42 | v -9.562160 1.352654 -8.258186 43 | v 9.584381 1.352654 -19.503151 44 | v -9.562160 1.352654 -19.503151 45 | v 9.584381 0.083778 -19.503151 46 | v -9.562160 0.083778 -19.503151 47 | v -1.992085 1.352654 -8.258186 48 | v 1.971237 1.352654 -8.258186 49 | v 2.209644 0.083779 27.468933 50 | v 6.801266 0.083779 27.468933 51 | v 1.806809 1.352654 -19.503151 52 | v 1.807727 0.083778 -19.503151 53 | v -1.833586 1.352654 -19.503151 54 | v -1.841699 0.083778 -19.503151 55 | v -1.837642 0.718216 -19.503151 56 | v 1.807268 0.718216 -19.503151 57 | v -1.837642 0.718216 -21.191490 58 | v 1.807268 0.718216 -21.191490 59 | v 1.807727 0.083778 -21.191490 60 | v -1.841699 0.083778 -21.191490 61 | v 1.806809 1.352654 -20.349506 62 | v -1.833586 1.352654 -20.349506 63 | v 1.807268 0.718216 -20.349506 64 | v -1.837642 0.718216 -20.349506 65 | v 0.011112 21.366768 -9.865997 66 | v -12.056731 10.675596 -9.865997 67 | v 12.222922 10.718573 -9.865997 68 | v 0.011112 21.366768 29.076740 69 | v -12.056731 10.675596 29.076740 70 | v 12.222922 10.718573 29.076740 71 | v -11.696275 10.437319 29.076740 72 | v 0.304019 21.104111 29.076740 73 | v -0.004865 20.825569 29.076740 74 | v 11.855354 10.426807 29.076740 75 | v 11.855874 10.427299 -9.865997 76 | v -0.287550 21.098951 -9.865997 77 | v -0.005755 20.844450 -9.865997 78 | v -11.697057 10.436284 -9.865997 79 | v -8.314565 1.178085 -14.690422 80 | v -8.113598 1.178085 -14.460913 81 | v -7.723187 1.178085 -14.383255 82 | v -7.370952 1.178085 -14.590198 83 | v -7.314556 1.178085 -14.994815 84 | v -7.524743 1.178085 -15.342196 85 | v -7.926116 1.178085 -15.403445 86 | v -8.292524 1.178085 -15.172796 87 | v -8.314565 11.530749 -14.690422 88 | v -8.113598 11.530749 -14.460913 89 | v -7.723187 11.530748 -14.383255 90 | v -7.370952 11.530749 -14.590198 91 | v -7.314556 11.530749 -14.994815 92 | v -7.524743 11.530749 -15.342196 93 | v -7.926116 11.530748 -15.403445 94 | v -8.292524 11.530749 -15.172796 95 | v 9.735872 10.919974 -18.191801 96 | v -9.593304 10.919974 -18.191801 97 | v 9.735872 11.318687 -18.241917 98 | v -9.593304 11.318687 -18.241917 99 | v 9.732642 12.788167 -8.232523 100 | v -9.596533 12.788167 -8.232523 101 | v 9.732642 12.389454 -8.182407 102 | v -9.596533 12.389454 -8.182407 103 | v 7.189742 1.178085 -14.690422 104 | v 7.390709 1.178085 -14.460913 105 | v 7.781119 1.178085 -14.383255 106 | v 8.133354 1.178085 -14.590198 107 | v 8.189751 1.178085 -14.994815 108 | v 7.979564 1.178085 -15.342196 109 | v 7.578191 1.178085 -15.403445 110 | v 7.211783 1.178085 -15.172796 111 | v 7.189742 11.530749 -14.690422 112 | v 7.390709 11.530749 -14.460913 113 | v 7.781119 11.530751 -14.383255 114 | v 8.133354 11.530749 -14.590198 115 | v 8.189751 11.530751 -14.994815 116 | v 7.979564 11.530751 -15.342196 117 | v 7.578191 11.530751 -15.403445 118 | v 7.211783 11.530751 -15.172796 119 | v 2.619709 18.727844 -8.258188 120 | v 4.744160 16.822790 -8.258188 121 | v 1.119221 16.805269 -8.258187 122 | v 1.143524 18.726208 -8.258187 123 | v -1.461399 18.724052 -8.258185 124 | v -1.462166 16.794991 -8.258185 125 | v -4.775525 16.774738 -8.258185 126 | v -2.603912 18.722082 -8.258185 127 | v 0.011108 21.067041 -8.258188 128 | v 2.619709 18.727844 -8.258188 129 | v 1.143524 18.726208 -8.258188 130 | v -1.461399 18.724052 -8.258188 131 | v -2.603913 18.722082 -8.258188 132 | v -1.992084 1.352655 -8.258186 133 | v -2.023838 8.915440 -8.258186 134 | v -2.023838 8.915440 -8.054993 135 | v -1.992084 1.352655 -8.054985 136 | v 1.971237 1.352654 -8.258186 137 | v -1.992085 1.352654 -8.258186 138 | v -1.992085 1.352654 -8.054985 139 | v 1.971237 1.352654 -8.054985 140 | v 1.971210 8.917807 -8.258186 141 | v 1.971237 1.352654 -8.258186 142 | v 1.971237 1.352654 -8.054985 143 | v 1.971210 8.917807 -8.054985 144 | v -2.023838 8.915439 -8.258186 145 | v 1.971210 8.917806 -8.258186 146 | v 1.971210 8.917806 -8.054985 147 | v -2.023838 8.915439 -8.054993 148 | v -9.562161 8.910973 -8.258187 149 | v -2.023839 8.915440 -8.258186 150 | v -1.992085 1.352655 -8.258186 151 | v -9.562161 1.352655 -8.258187 152 | v -9.562161 2.967356 -8.258187 153 | v -9.562160 12.482436 -8.258186 154 | v 9.584381 12.482436 -8.258186 155 | v 9.584381 8.922317 -8.258186 156 | v 1.971210 8.917807 -8.258186 157 | v -2.023838 8.915440 -8.258186 158 | v -9.562160 8.910972 -8.258186 159 | v 1.971211 8.917807 -8.258186 160 | v 9.584381 8.922317 -8.258186 161 | v 9.584381 2.967085 -8.258186 162 | v 9.584381 1.352654 -8.258186 163 | v 1.971238 1.352655 -8.258186 164 | v 4.744160 16.822790 -8.258186 165 | v 9.584381 12.482436 -8.258186 166 | v -9.562160 12.482436 -8.258186 167 | v -4.775524 16.774738 -8.258186 168 | v -1.462166 16.794991 -8.258186 169 | v 1.119221 16.805269 -8.258186 170 | v 1.191590 18.761831 -8.239181 171 | v 1.166390 16.770023 -8.239181 172 | v -1.510232 16.759363 -8.239181 173 | v -1.509437 18.759594 -8.239181 174 | v 0.011108 21.067041 27.468933 175 | v -2.577679 18.745605 27.468933 176 | v -1.464676 18.744141 27.468933 177 | v 1.113865 18.740747 27.468933 178 | v 2.607510 18.738783 27.468933 179 | v 9.584381 12.482435 27.468931 180 | v -9.562160 12.482435 27.468931 181 | v -9.562160 8.950749 27.468931 182 | v 2.229404 8.950924 27.468931 183 | v 6.757504 8.950987 27.468931 184 | v 9.584381 8.951014 27.468931 185 | v 9.584381 8.951015 27.468933 186 | v 6.757504 8.950988 27.468933 187 | v 6.801266 0.083779 27.468933 188 | v 9.584381 0.083779 27.468933 189 | v 9.584381 2.931374 27.468933 190 | v 2.229405 8.950925 27.468933 191 | v -9.562161 8.950750 27.468935 192 | v -9.562161 2.930227 27.468935 193 | v -9.562161 0.083780 27.468935 194 | v 2.209645 0.083779 27.468933 195 | v 6.757504 8.950987 27.468933 196 | v 2.229404 8.950925 27.468933 197 | v 2.229404 8.950925 27.234821 198 | v 6.757504 8.950987 27.234821 199 | v 2.229404 8.950925 27.468925 200 | v 2.209644 0.083779 27.468933 201 | v 2.209644 0.083779 27.234818 202 | v 2.229404 8.950925 27.234814 203 | v 6.801266 0.083779 27.468933 204 | v 6.757504 8.950988 27.468931 205 | v 6.757504 8.950988 27.234819 206 | v 6.801266 0.083778 27.234821 207 | v 1.113865 18.740747 27.468937 208 | v 1.128643 16.955921 27.468937 209 | v 4.593323 16.958052 27.468935 210 | v 2.607509 18.738783 27.468937 211 | v -4.577393 16.952412 27.468931 212 | v -9.562160 12.482436 27.468931 213 | v 9.584381 12.482436 27.468931 214 | v 4.593323 16.958052 27.468931 215 | v 1.128643 16.955921 27.468931 216 | v -1.479530 16.954317 27.468931 217 | v -2.577679 18.745607 27.468931 218 | v -4.577393 16.952414 27.468931 219 | v -1.479530 16.954319 27.468931 220 | v -1.464676 18.744143 27.468931 221 | v 2.209645 0.083779 28.635662 222 | v 6.801266 0.083779 28.635662 223 | v 6.801266 0.630622 28.635662 224 | v 2.209645 0.630622 28.635662 225 | v 2.209645 0.083779 27.468933 226 | v 6.801266 0.083779 27.468929 227 | v 6.801266 0.083779 28.635658 228 | v 2.209645 0.083779 28.635662 229 | v 6.801265 0.083779 27.468931 230 | v 6.801265 0.630622 27.468931 231 | v 6.801265 0.630621 28.635660 232 | v 6.801265 0.083779 28.635660 233 | v 6.801266 0.630621 27.468929 234 | v 2.209645 0.630622 27.468933 235 | v 2.209645 0.630622 28.635662 236 | v 6.801266 0.630621 28.635658 237 | v 2.209645 0.630622 27.468933 238 | v 2.209645 0.083779 27.468933 239 | v 2.209645 0.083779 28.635662 240 | v 2.209645 0.630622 28.635662 241 | v -1.519492 18.771900 27.427946 242 | v -1.534808 16.926554 27.427946 243 | v 1.154275 16.928207 27.427946 244 | v 1.139039 18.768402 27.427946 245 | v 9.584380 8.943011 17.507133 246 | v 9.584380 8.951015 27.468933 247 | v 9.584380 2.931374 27.468933 248 | v 9.584376 2.941292 17.546253 249 | v 9.584382 12.482435 -8.258186 250 | v 9.584384 12.482436 27.468933 251 | v 9.584384 8.951015 27.468933 252 | v 9.584383 8.943011 17.507133 253 | v 9.584383 8.939797 13.505859 254 | v 9.584379 8.933404 5.542252 255 | v 9.584382 8.930156 1.501781 256 | v 9.584382 8.922316 -8.258186 257 | v 9.584383 2.967085 -8.258185 258 | v 9.584382 2.957290 1.540962 259 | v 9.584378 2.953252 5.581184 260 | v 9.584376 2.945292 13.544765 261 | v 9.584376 2.941292 17.546251 262 | v 9.584379 2.931375 27.468931 263 | v 9.584379 0.083779 27.468931 264 | v 9.584383 0.083778 -8.258185 265 | v 9.584383 1.352654 -8.258185 266 | v 9.584380 8.922316 -8.258185 267 | v 9.584381 8.930156 1.501782 268 | v 9.584381 2.957291 1.540963 269 | v 9.584380 2.967084 -8.258186 270 | v 9.584377 8.933404 5.542251 271 | v 9.584381 8.939797 13.505858 272 | v 9.584377 2.945292 13.544765 273 | v 9.584377 2.953252 5.581184 274 | v 9.584381 8.930156 1.501781 275 | v 9.584377 8.933404 5.542252 276 | v 9.264278 8.933404 5.542252 277 | v 9.264278 8.930156 1.501781 278 | v 9.584377 8.933404 5.542253 279 | v 9.584377 2.953252 5.581185 280 | v 9.264278 2.953253 5.581185 281 | v 9.264278 8.933404 5.542253 282 | v 9.584377 2.953252 5.581185 283 | v 9.584381 2.957291 1.540963 284 | v 9.264278 2.957291 1.540963 285 | v 9.264278 2.953253 5.581185 286 | v 9.584381 2.957291 1.540962 287 | v 9.584381 8.930156 1.501782 288 | v 9.264278 8.930156 1.501782 289 | v 9.264278 2.957291 1.540962 290 | v 9.584380 8.939797 13.505860 291 | v 9.584380 8.943010 17.507133 292 | v 9.264277 8.943010 17.507133 293 | v 9.264277 8.939797 13.505860 294 | v 9.584381 8.943011 17.507135 295 | v 9.584377 2.941292 17.546255 296 | v 9.264278 2.941292 17.546255 297 | v 9.264278 8.943011 17.507135 298 | v 9.584376 2.941292 17.546253 299 | v 9.584376 2.945292 13.544766 300 | v 9.264277 2.945292 13.544766 301 | v 9.264277 2.941292 17.546253 302 | v 9.584376 2.945292 13.544764 303 | v 9.584380 8.939797 13.505857 304 | v 9.264277 8.939797 13.505857 305 | v 9.264277 2.945292 13.544764 306 | v 9.495608 8.930156 1.501783 307 | v 9.495607 8.933403 5.542251 308 | v 9.495606 2.953253 5.581186 309 | v 9.495606 2.957292 1.540963 310 | v 9.495607 8.939797 13.505859 311 | v 9.495606 8.943011 17.507132 312 | v 9.495606 2.941293 17.546253 313 | v 9.495606 2.945292 13.544765 314 | v -9.562159 12.482434 27.468931 315 | v -9.562160 12.482436 -8.258185 316 | v -9.562160 8.910972 -8.258185 317 | v -9.562160 8.921830 1.494385 318 | v -9.562160 8.926348 5.552868 319 | v -9.562160 8.935206 13.510811 320 | v -9.562160 8.939658 17.508865 321 | v -9.562159 8.950748 27.468931 322 | v -9.562160 2.930226 27.468933 323 | v -9.562160 2.940577 17.508739 324 | v -9.562160 2.944732 13.510971 325 | v -9.562160 2.952961 5.592434 326 | v -9.562160 2.957179 1.534298 327 | v -9.562160 2.967356 -8.258186 328 | v -9.562160 1.352654 -8.258186 329 | v -9.562160 0.083778 -8.258186 330 | v -9.562160 0.083779 27.468933 331 | v -9.562162 8.921831 1.494385 332 | v -9.562162 8.910971 -8.258186 333 | v -9.562162 2.967355 -8.258186 334 | v -9.562161 2.957179 1.534298 335 | v -9.562160 8.950750 27.468933 336 | v -9.562160 8.939660 17.508865 337 | v -9.562160 2.940577 17.508739 338 | v -9.562160 2.930226 27.468933 339 | v -9.562161 8.935208 13.510810 340 | v -9.562160 8.926349 5.552867 341 | v -9.562160 2.952961 5.592433 342 | v -9.562161 2.944732 13.510970 343 | v -9.562160 8.939660 17.508863 344 | v -9.562160 8.935207 13.510810 345 | v -9.205691 8.935208 13.510810 346 | v -9.205691 8.939660 17.508863 347 | v -9.562160 8.935208 13.510814 348 | v -9.562160 2.944733 13.510974 349 | v -9.205692 2.944733 13.510974 350 | v -9.205692 8.935208 13.510814 351 | v -9.562160 2.944732 13.510972 352 | v -9.562160 2.940577 17.508739 353 | v -9.205692 2.940577 17.508739 354 | v -9.205692 2.944732 13.510972 355 | v -9.562160 2.940577 17.508739 356 | v -9.562160 8.939660 17.508865 357 | v -9.205692 8.939660 17.508865 358 | v -9.205692 2.940577 17.508739 359 | v -9.562160 8.926348 5.552868 360 | v -9.562160 8.921830 1.494385 361 | v -9.205688 8.921831 1.494385 362 | v -9.205688 8.926349 5.552868 363 | v -9.562160 8.921832 1.494385 364 | v -9.562160 2.957179 1.534298 365 | v -9.205692 2.957179 1.534298 366 | v -9.205688 8.921832 1.494385 367 | v -9.562160 2.957179 1.534298 368 | v -9.562160 2.952961 5.592434 369 | v -9.205691 2.952960 5.592434 370 | v -9.205691 2.957178 1.534298 371 | v -9.562160 2.952962 5.592435 372 | v -9.562160 8.926350 5.552869 373 | v -9.205688 8.926350 5.552869 374 | v -9.205692 2.952961 5.592435 375 | v -9.525482 8.939660 17.508865 376 | v -9.525482 8.935208 13.510809 377 | v -9.525482 2.944733 13.510973 378 | v -9.525482 2.940578 17.508739 379 | v -9.525481 8.926349 5.552868 380 | v -9.525481 8.921831 1.494385 381 | v -9.525482 2.957179 1.534299 382 | v -9.525481 2.952961 5.592433 383 | vt 0.335384 0.116530 384 | vt 0.280210 0.116678 385 | vt 0.280210 0.016955 386 | vt 0.334945 0.016839 387 | vt 0.120697 0.922537 388 | vt 0.120697 0.931018 389 | vt 0.114753 0.931018 390 | vt 0.114753 0.922537 391 | vt 0.114753 0.736764 392 | vt 0.114753 0.728464 393 | vt 0.120697 0.728464 394 | vt 0.120697 0.736764 395 | vt 0.188456 0.922537 396 | vt 0.188456 0.931018 397 | vt 0.122494 0.931018 398 | vt 0.122494 0.922537 399 | vt 0.122494 0.736764 400 | vt 0.122494 0.728464 401 | vt 0.188456 0.728464 402 | vt 0.188456 0.736764 403 | vt 0.231976 0.921577 404 | vt 0.240457 0.921577 405 | vt 0.240457 0.977777 406 | vt 0.231976 0.977777 407 | vt 0.327238 0.903655 408 | vt 0.321144 0.904703 409 | vt 0.309517 0.837074 410 | vt 0.315611 0.836027 411 | vt 0.346270 0.840277 412 | vt 0.333553 0.895421 413 | vt 0.255941 0.914237 414 | vt 0.189979 0.914237 415 | vt 0.189979 0.728464 416 | vt 0.255941 0.728464 417 | vt 0.216639 0.978016 418 | vt 0.216639 0.921816 419 | vt 0.224939 0.921816 420 | vt 0.224939 0.978016 421 | vt 0.076840 0.736764 422 | vt 0.070896 0.728464 423 | vt 0.076840 0.728464 424 | vt 0.107779 0.728464 425 | vt 0.107779 0.736764 426 | vt 0.294892 0.984607 427 | vt 0.298500 0.916081 428 | vt 0.305737 0.923517 429 | vt 0.324841 0.976786 430 | vt 0.109372 0.931018 431 | vt 0.109372 0.922537 432 | vt 0.278520 0.916139 433 | vt 0.284888 0.984463 434 | vt 0.254649 0.977857 435 | vt 0.271588 0.923860 436 | vt 0.278919 0.901412 437 | vt 0.273537 0.892541 438 | vt 0.266894 0.836340 439 | vt 0.297833 0.835450 440 | vt 0.303777 0.837154 441 | vt 0.284863 0.903117 442 | vt 0.109372 0.736764 443 | vt 0.109372 0.728464 444 | vt 0.076840 0.922537 445 | vt 0.070896 0.931018 446 | vt 0.070896 0.922537 447 | vt 0.070896 0.736764 448 | vt 0.107779 0.922537 449 | vt 0.107779 0.931018 450 | vt 0.076840 0.931018 451 | vt 0.394524 0.116949 452 | vt 0.340113 0.116949 453 | vt 0.339876 0.017110 454 | vt 0.395050 0.017110 455 | vt 0.856066 0.899668 456 | vt 0.856066 0.850832 457 | vt 0.860075 0.850858 458 | vt 0.864084 0.850883 459 | vt 0.864084 0.899668 460 | vt 0.850650 0.849837 461 | vt 0.850650 0.802002 462 | vt 0.850650 0.776958 463 | vt 0.850650 0.728851 464 | vt 0.921706 0.728851 465 | vt 0.921706 0.777997 466 | vt 0.921706 0.801000 467 | vt 0.921706 0.849837 468 | vt 0.883179 0.921888 469 | vt 0.875161 0.921888 470 | vt 0.875161 0.850832 471 | vt 0.883179 0.850832 472 | vt 0.727676 0.728851 473 | vt 0.848662 0.728851 474 | vt 0.848662 0.954609 475 | vt 0.831076 0.954609 476 | vt 0.802062 0.954609 477 | vt 0.727676 0.954609 478 | vt 0.884708 0.850832 479 | vt 0.892726 0.850832 480 | vt 0.892726 0.921888 481 | vt 0.884708 0.921888 482 | vt 0.975981 0.971818 483 | vt 0.904924 0.971818 484 | vt 0.904924 0.923033 485 | vt 0.904924 0.899972 486 | vt 0.904924 0.850832 487 | vt 0.975981 0.850832 488 | vt 0.928875 0.849837 489 | vt 0.928875 0.728851 490 | vt 0.936893 0.728851 491 | vt 0.936893 0.849837 492 | vt 0.865614 0.899978 493 | vt 0.865614 0.850832 494 | vt 0.873632 0.850832 495 | vt 0.873632 0.899972 496 | vt 0.869623 0.899975 497 | vt 0.850528 0.873867 498 | vt 0.850528 0.850835 499 | vt 0.854537 0.850832 500 | vt 0.854537 0.873893 501 | vt 0.825914 0.978610 502 | vt 0.825914 0.955607 503 | vt 0.829923 0.955604 504 | vt 0.829923 0.978636 505 | vt 0.838330 0.978636 506 | vt 0.838330 0.955604 507 | vt 0.848998 0.955604 508 | vt 0.848998 0.978636 509 | vt 0.824384 0.966272 510 | vt 0.820375 0.966272 511 | vt 0.820375 0.955604 512 | vt 0.824384 0.955604 513 | vt 0.894256 0.923033 514 | vt 0.894256 0.899972 515 | vt 0.814837 0.955604 516 | vt 0.818846 0.955604 517 | vt 0.818846 0.966272 518 | vt 0.814837 0.966272 519 | vt 0.927054 0.777997 520 | vt 0.927054 0.801000 521 | vt 0.813307 0.960952 522 | vt 0.809298 0.960952 523 | vt 0.809298 0.955604 524 | vt 0.813307 0.955604 525 | vt 0.836800 0.955604 526 | vt 0.836800 0.978636 527 | vt 0.831452 0.978636 528 | vt 0.831452 0.955604 529 | vt 0.803760 0.955604 530 | vt 0.807769 0.955604 531 | vt 0.807769 0.960952 532 | vt 0.803760 0.960952 533 | vt 0.055985 0.613791 534 | vt 0.055990 0.609277 535 | vt 0.056184 0.433443 536 | vt 0.239914 0.433569 537 | vt 0.239715 0.613917 538 | vt 0.056178 0.429988 539 | vt 0.239908 0.430130 540 | vt 0.462643 0.435340 541 | vt 0.462844 0.613531 542 | vt 0.279116 0.613393 543 | vt 0.279111 0.608988 544 | vt 0.278915 0.435201 545 | vt 0.492235 0.139417 546 | vt 0.430423 0.019776 547 | vt 0.432281 0.016521 548 | vt 0.492321 0.133564 549 | vt 0.493747 0.136423 550 | vt 0.646759 0.138675 551 | vt 0.585676 0.018449 552 | vt 0.587501 0.015779 553 | vt 0.646678 0.132598 554 | vt 0.648242 0.135731 555 | vt 0.706711 0.016038 556 | vt 0.708571 0.019320 557 | vt 0.551498 0.017231 558 | vt 0.553318 0.019923 559 | vt 0.278921 0.429602 560 | vt 0.462649 0.429750 561 | vt 0.641858 0.626531 562 | vt 0.579517 0.626531 563 | vt 0.579512 0.421835 564 | vt 0.641861 0.421835 565 | vt 0.518063 0.626531 566 | vt 0.518059 0.421835 567 | vt 0.555138 0.729358 568 | vt 0.559289 0.729358 569 | vt 0.559289 0.943193 570 | vt 0.555138 0.943193 571 | vt 0.567352 0.729358 572 | vt 0.567352 0.943193 573 | vt 0.574628 0.729358 574 | vt 0.574628 0.943193 575 | vt 0.576168 0.729358 576 | vt 0.584525 0.729358 577 | vt 0.584525 0.943193 578 | vt 0.576168 0.943193 579 | vt 0.591700 0.729358 580 | vt 0.591700 0.943193 581 | vt 0.609130 0.943193 582 | vt 0.600840 0.943193 583 | vt 0.600840 0.729358 584 | vt 0.609130 0.729358 585 | vt 0.593271 0.943193 586 | vt 0.593271 0.729358 587 | vt 0.610375 0.729358 588 | vt 0.620339 0.729358 589 | vt 0.620339 0.943193 590 | vt 0.610375 0.943193 591 | vt 0.621648 0.744085 592 | vt 0.622103 0.734122 593 | vt 0.629672 0.729358 594 | vt 0.637962 0.730623 595 | vt 0.642304 0.737798 596 | vt 0.641139 0.746156 597 | vt 0.633863 0.750430 598 | vt 0.625799 0.748826 599 | vt 0.643806 0.735702 600 | vt 0.647956 0.730962 601 | vt 0.656020 0.729358 602 | vt 0.663296 0.733632 603 | vt 0.664461 0.741990 604 | vt 0.660119 0.749165 605 | vt 0.651829 0.750430 606 | vt 0.644261 0.745666 607 | vt 0.932359 0.417110 608 | vt 0.932359 0.622662 609 | vt 0.928119 0.622662 610 | vt 0.928119 0.417110 611 | vt 0.812371 0.417110 612 | vt 0.812371 0.622662 613 | vt 0.705929 0.622696 614 | vt 0.705929 0.417144 615 | vt 0.926487 0.417110 616 | vt 0.926487 0.622662 617 | vt 0.922247 0.622662 618 | vt 0.922247 0.417110 619 | vt 0.920555 0.417144 620 | vt 0.920555 0.622696 621 | vt 0.814112 0.622662 622 | vt 0.814112 0.417110 623 | vt 0.943500 0.521522 624 | vt 0.943710 0.413939 625 | vt 0.947982 0.413858 626 | vt 0.947773 0.521442 627 | vt 0.944013 0.632327 628 | vt 0.943818 0.524743 629 | vt 0.948091 0.524824 630 | vt 0.948286 0.632408 631 | vt 0.423509 0.729062 632 | vt 0.427660 0.729062 633 | vt 0.427660 0.942897 634 | vt 0.423509 0.942897 635 | vt 0.435724 0.729062 636 | vt 0.435724 0.942897 637 | vt 0.443000 0.729062 638 | vt 0.443000 0.942897 639 | vt 0.444539 0.729062 640 | vt 0.452896 0.729062 641 | vt 0.452896 0.942897 642 | vt 0.444539 0.942897 643 | vt 0.460072 0.729062 644 | vt 0.460072 0.942897 645 | vt 0.488774 0.942897 646 | vt 0.480484 0.942897 647 | vt 0.480484 0.729062 648 | vt 0.488774 0.729062 649 | vt 0.472916 0.942897 650 | vt 0.472916 0.729062 651 | vt 0.461643 0.729062 652 | vt 0.471606 0.729062 653 | vt 0.471606 0.942897 654 | vt 0.461643 0.942897 655 | vt 0.490020 0.743790 656 | vt 0.490475 0.733826 657 | vt 0.498043 0.729062 658 | vt 0.506334 0.730327 659 | vt 0.510675 0.737503 660 | vt 0.509510 0.745860 661 | vt 0.502235 0.750134 662 | vt 0.494171 0.748530 663 | vt 0.512177 0.735407 664 | vt 0.516328 0.730666 665 | vt 0.524392 0.729062 666 | vt 0.531667 0.733337 667 | vt 0.532832 0.741694 668 | vt 0.528491 0.748869 669 | vt 0.520200 0.750134 670 | vt 0.512632 0.745370 671 | vt 0.666231 0.368129 672 | vt 0.690919 0.346629 673 | vt 0.648795 0.346431 674 | vt 0.649077 0.368111 675 | vt 0.618806 0.368086 676 | vt 0.618797 0.346315 677 | vt 0.580293 0.346086 678 | vt 0.605529 0.368064 679 | vt 0.635917 0.394530 680 | vt 0.666231 0.368129 681 | vt 0.649077 0.368111 682 | vt 0.618806 0.368086 683 | vt 0.605529 0.368064 684 | vt 0.612639 0.172032 685 | vt 0.612270 0.257386 686 | vt 0.612270 0.257386 687 | vt 0.612639 0.172032 688 | vt 0.658696 0.172032 689 | vt 0.612639 0.172032 690 | vt 0.612639 0.172032 691 | vt 0.658696 0.172032 692 | vt 0.658695 0.257413 693 | vt 0.658696 0.172032 694 | vt 0.658696 0.172032 695 | vt 0.658695 0.257413 696 | vt 0.612270 0.257386 697 | vt 0.658695 0.257413 698 | vt 0.658695 0.257413 699 | vt 0.612270 0.257386 700 | vt 0.524669 0.257336 701 | vt 0.612270 0.257386 702 | vt 0.612639 0.172032 703 | vt 0.524669 0.172032 704 | vt 0.524669 0.190256 705 | vt 0.524669 0.297643 706 | vt 0.747166 0.297643 707 | vt 0.747166 0.257464 708 | vt 0.658695 0.257413 709 | vt 0.612270 0.257386 710 | vt 0.524669 0.257336 711 | vt 0.658695 0.257413 712 | vt 0.747166 0.257464 713 | vt 0.747166 0.190253 714 | vt 0.747166 0.172032 715 | vt 0.658696 0.172032 716 | vt 0.690919 0.346629 717 | vt 0.747166 0.297643 718 | vt 0.524669 0.297643 719 | vt 0.580293 0.346086 720 | vt 0.618797 0.346315 721 | vt 0.648795 0.346431 722 | vt 0.649077 0.368111 723 | vt 0.648795 0.346431 724 | vt 0.618797 0.346315 725 | vt 0.618806 0.368086 726 | vt 0.867823 0.390611 727 | vt 0.837739 0.365995 728 | vt 0.850673 0.365980 729 | vt 0.880638 0.365944 730 | vt 0.897995 0.365923 731 | vt 0.979072 0.299583 732 | vt 0.756574 0.299583 733 | vt 0.756574 0.262135 734 | vt 0.893601 0.262137 735 | vt 0.946221 0.262137 736 | vt 0.979072 0.262138 737 | vt 0.979072 0.262138 738 | vt 0.946221 0.262137 739 | vt 0.946729 0.168113 740 | vt 0.979072 0.168113 741 | vt 0.979072 0.198308 742 | vt 0.893601 0.262137 743 | vt 0.756574 0.262135 744 | vt 0.756574 0.198296 745 | vt 0.756574 0.168113 746 | vt 0.893372 0.168113 747 | vt 0.946221 0.262137 748 | vt 0.893601 0.262137 749 | vt 0.893601 0.262137 750 | vt 0.946221 0.262137 751 | vt 0.893601 0.262137 752 | vt 0.893372 0.168113 753 | vt 0.893372 0.168113 754 | vt 0.893601 0.262137 755 | vt 0.946729 0.168113 756 | vt 0.946221 0.262137 757 | vt 0.946221 0.262137 758 | vt 0.946729 0.168113 759 | vt 0.880638 0.365944 760 | vt 0.880809 0.347018 761 | vt 0.921072 0.347041 762 | vt 0.897995 0.365923 763 | vt 0.814501 0.346981 764 | vt 0.756574 0.299583 765 | vt 0.979072 0.299583 766 | vt 0.921072 0.347041 767 | vt 0.880809 0.347018 768 | vt 0.850500 0.347001 769 | vt 0.837739 0.365995 770 | vt 0.814501 0.346981 771 | vt 0.850500 0.347001 772 | vt 0.850673 0.365980 773 | vt 0.893372 0.168113 774 | vt 0.946729 0.168113 775 | vt 0.946729 0.173912 776 | vt 0.893372 0.173912 777 | vt 0.893372 0.168113 778 | vt 0.946729 0.168113 779 | vt 0.946729 0.168113 780 | vt 0.893372 0.168113 781 | vt 0.946729 0.168113 782 | vt 0.946729 0.173912 783 | vt 0.946729 0.173912 784 | vt 0.946729 0.168113 785 | vt 0.946729 0.173912 786 | vt 0.893372 0.173912 787 | vt 0.893372 0.173912 788 | vt 0.946729 0.173912 789 | vt 0.893372 0.173912 790 | vt 0.893372 0.168113 791 | vt 0.893372 0.168113 792 | vt 0.893372 0.173912 793 | vt 0.850141 0.365980 794 | vt 0.849968 0.347001 795 | vt 0.880278 0.347018 796 | vt 0.880106 0.365944 797 | vt 0.333012 0.286816 798 | vt 0.267217 0.286922 799 | vt 0.267217 0.206526 800 | vt 0.332754 0.206658 801 | vt 0.503187 0.334087 802 | vt 0.267217 0.334087 803 | vt 0.267217 0.286922 804 | vt 0.333012 0.286816 805 | vt 0.359440 0.286773 806 | vt 0.412038 0.286687 807 | vt 0.438724 0.286644 808 | vt 0.503187 0.286539 809 | vt 0.503187 0.207003 810 | vt 0.438465 0.206872 811 | vt 0.411781 0.206818 812 | vt 0.359183 0.206712 813 | vt 0.332754 0.206658 814 | vt 0.267217 0.206526 815 | vt 0.267217 0.168494 816 | vt 0.503187 0.168494 817 | vt 0.503187 0.185441 818 | vt 0.503187 0.286539 819 | vt 0.438724 0.286644 820 | vt 0.438465 0.206872 821 | vt 0.503187 0.207003 822 | vt 0.412038 0.286687 823 | vt 0.359440 0.286773 824 | vt 0.359183 0.206712 825 | vt 0.411781 0.206818 826 | vt 0.438724 0.286644 827 | vt 0.412038 0.286687 828 | vt 0.412038 0.286687 829 | vt 0.438724 0.286644 830 | vt 0.412038 0.286687 831 | vt 0.411781 0.206818 832 | vt 0.411781 0.206818 833 | vt 0.412038 0.286687 834 | vt 0.411781 0.206818 835 | vt 0.438465 0.206872 836 | vt 0.438465 0.206872 837 | vt 0.411781 0.206818 838 | vt 0.438465 0.206872 839 | vt 0.438724 0.286644 840 | vt 0.438724 0.286644 841 | vt 0.438465 0.206872 842 | vt 0.359440 0.286773 843 | vt 0.333012 0.286816 844 | vt 0.333012 0.286816 845 | vt 0.359440 0.286773 846 | vt 0.333012 0.286816 847 | vt 0.332754 0.206658 848 | vt 0.332754 0.206658 849 | vt 0.333012 0.286816 850 | vt 0.332754 0.206658 851 | vt 0.359183 0.206712 852 | vt 0.359183 0.206712 853 | vt 0.332754 0.206658 854 | vt 0.359183 0.206712 855 | vt 0.359440 0.286773 856 | vt 0.359440 0.286773 857 | vt 0.359183 0.206712 858 | vt 0.438724 0.286644 859 | vt 0.412038 0.286687 860 | vt 0.411781 0.206818 861 | vt 0.438465 0.206872 862 | vt 0.359440 0.286773 863 | vt 0.333012 0.286816 864 | vt 0.332754 0.206658 865 | vt 0.359183 0.206712 866 | vt 0.014362 0.335299 867 | vt 0.250332 0.335299 868 | vt 0.250332 0.287600 869 | vt 0.185919 0.287745 870 | vt 0.159113 0.287805 871 | vt 0.106553 0.287923 872 | vt 0.080146 0.287983 873 | vt 0.014362 0.288131 874 | vt 0.014362 0.207723 875 | vt 0.080147 0.207861 876 | vt 0.106552 0.207916 877 | vt 0.158852 0.208026 878 | vt 0.185655 0.208082 879 | vt 0.250332 0.208218 880 | vt 0.250332 0.186653 881 | vt 0.250332 0.169706 882 | vt 0.014362 0.169706 883 | vt 0.185919 0.287745 884 | vt 0.250332 0.287600 885 | vt 0.250332 0.208218 886 | vt 0.185655 0.208082 887 | vt 0.014362 0.288131 888 | vt 0.080146 0.287983 889 | vt 0.080147 0.207861 890 | vt 0.014362 0.207723 891 | vt 0.106553 0.287923 892 | vt 0.159113 0.287805 893 | vt 0.158852 0.208026 894 | vt 0.106552 0.207916 895 | vt 0.080146 0.287983 896 | vt 0.106553 0.287923 897 | vt 0.106553 0.287923 898 | vt 0.080146 0.287983 899 | vt 0.106552 0.287923 900 | vt 0.106552 0.207916 901 | vt 0.106552 0.207916 902 | vt 0.106552 0.287923 903 | vt 0.106552 0.207916 904 | vt 0.080147 0.207861 905 | vt 0.080147 0.207861 906 | vt 0.106552 0.207916 907 | vt 0.080147 0.207861 908 | vt 0.080146 0.287983 909 | vt 0.080146 0.287983 910 | vt 0.080147 0.207861 911 | vt 0.159113 0.287805 912 | vt 0.185919 0.287745 913 | vt 0.185919 0.287745 914 | vt 0.159113 0.287805 915 | vt 0.185919 0.287745 916 | vt 0.185655 0.208082 917 | vt 0.185655 0.208082 918 | vt 0.185919 0.287745 919 | vt 0.185655 0.208082 920 | vt 0.158852 0.208026 921 | vt 0.158852 0.208026 922 | vt 0.185655 0.208082 923 | vt 0.158852 0.208026 924 | vt 0.159113 0.287805 925 | vt 0.159113 0.287805 926 | vt 0.158852 0.208026 927 | vt 0.080146 0.287983 928 | vt 0.106553 0.287923 929 | vt 0.106552 0.207916 930 | vt 0.080147 0.207861 931 | vt 0.159113 0.287805 932 | vt 0.185919 0.287745 933 | vt 0.185655 0.208082 934 | vt 0.158852 0.208026 935 | vn 0.000001 -0.000000 -1.000000 936 | vn 0.000001 -0.000000 -1.000000 937 | vn 0.000001 -0.000000 -1.000000 938 | vn 0.000001 -0.000000 -1.000000 939 | vn 0.000000 -0.275643 0.961260 940 | vn 0.000000 -0.275643 0.961260 941 | vn 0.000000 -0.607091 0.794632 942 | vn 0.000000 -0.607091 0.794632 943 | vn 0.000000 -0.607086 0.794636 944 | vn 0.000000 -0.607086 0.794636 945 | vn 0.000000 -0.275643 0.961260 946 | vn 0.000000 -0.275643 0.961260 947 | vn 0.000000 0.961262 0.275638 948 | vn 0.000000 0.961262 0.275638 949 | vn 0.000000 0.961262 0.275638 950 | vn 0.000000 0.961262 0.275638 951 | vn 0.000000 0.961262 0.275638 952 | vn 0.000000 0.961262 0.275638 953 | vn 0.000000 0.961262 0.275638 954 | vn 0.000000 0.961262 0.275638 955 | vn 0.000000 -0.993085 0.117394 956 | vn 0.000000 -0.993085 0.117394 957 | vn 0.000000 -0.993085 0.117394 958 | vn 0.000000 -0.993085 0.117394 959 | vn -1.000000 0.000000 0.000000 960 | vn -1.000000 0.000000 0.000000 961 | vn -1.000000 0.000000 0.000000 962 | vn -1.000000 0.000000 0.000000 963 | vn -1.000000 0.000000 0.000000 964 | vn -1.000000 0.000000 0.000000 965 | vn 0.000000 -0.961262 -0.275637 966 | vn 0.000000 -0.961262 -0.275637 967 | vn 0.000000 -0.961262 -0.275637 968 | vn 0.000000 -0.961262 -0.275637 969 | vn 0.000000 -0.993086 0.117394 970 | vn 0.000000 -0.993086 0.117394 971 | vn 0.000000 -0.993086 0.117394 972 | vn 0.000000 -0.993086 0.117394 973 | vn 0.000000 -0.001120 -0.999999 974 | vn 0.000000 -0.001120 -0.999999 975 | vn 0.000000 -0.001120 -0.999999 976 | vn 0.000000 -0.001120 -0.999999 977 | vn 0.000000 -0.001120 -0.999999 978 | vn 1.000000 -0.000000 0.000000 979 | vn 1.000000 -0.000000 0.000000 980 | vn 1.000000 -0.000000 0.000000 981 | vn 1.000000 -0.000000 0.000000 982 | vn 0.000000 -0.854990 0.518645 983 | vn 0.000000 -0.854990 0.518645 984 | vn -1.000000 0.000001 -0.000000 985 | vn -1.000000 0.000001 -0.000000 986 | vn -1.000000 0.000001 -0.000000 987 | vn -1.000000 0.000001 -0.000000 988 | vn 1.000000 -0.000001 0.000000 989 | vn 1.000000 -0.000001 0.000000 990 | vn 1.000000 -0.000001 0.000000 991 | vn 1.000000 -0.000001 0.000000 992 | vn 1.000000 -0.000001 0.000000 993 | vn 1.000000 -0.000001 0.000000 994 | vn 0.000000 -0.854983 0.518655 995 | vn 0.000000 -0.854983 0.518655 996 | vn 0.000000 0.275643 -0.961260 997 | vn 0.000000 0.275643 -0.961260 998 | vn 0.000000 0.275643 -0.961260 999 | vn 0.000000 0.275643 -0.961260 1000 | vn 0.000000 0.275643 -0.961260 1001 | vn 0.000000 0.275643 -0.961260 1002 | vn 0.000000 -0.001116 -0.999999 1003 | vn 0.000000 -0.001116 -0.999999 1004 | vn 0.000000 -0.001116 -0.999999 1005 | vn 0.000000 -0.001116 -0.999999 1006 | vn 0.000000 -0.001116 -0.999999 1007 | vn -0.000001 0.000000 1.000000 1008 | vn -0.000001 0.000000 1.000000 1009 | vn -0.000001 0.000000 1.000000 1010 | vn -0.000001 0.000000 1.000000 1011 | vn 0.000000 0.000000 -1.000000 1012 | vn 0.000000 0.000000 -1.000000 1013 | vn 0.000000 0.000000 -1.000000 1014 | vn 0.000000 0.000000 -1.000000 1015 | vn 0.000000 0.000000 -1.000000 1016 | vn -0.000000 1.000000 -0.000000 1017 | vn -0.000000 1.000000 -0.000000 1018 | vn -0.000000 1.000000 -0.000000 1019 | vn -0.000000 1.000000 -0.000000 1020 | vn -0.000000 1.000000 -0.000000 1021 | vn -0.000000 1.000000 -0.000000 1022 | vn -0.000000 1.000000 -0.000000 1023 | vn -0.000000 1.000000 -0.000000 1024 | vn 1.000000 0.000000 0.000000 1025 | vn 1.000000 0.000000 0.000000 1026 | vn 1.000000 0.000000 0.000000 1027 | vn 1.000000 0.000000 0.000000 1028 | vn 0.000000 -1.000000 0.000000 1029 | vn 0.000000 -1.000000 0.000000 1030 | vn 0.000000 -1.000000 0.000000 1031 | vn 0.000000 -1.000000 0.000000 1032 | vn 0.000000 -1.000000 0.000000 1033 | vn 0.000000 -1.000000 0.000000 1034 | vn -0.707107 0.000000 0.707107 1035 | vn -0.707107 0.000000 0.707107 1036 | vn -1.000000 0.000000 0.000000 1037 | vn -1.000000 0.000000 0.000000 1038 | vn 0.000000 -1.000000 -0.000000 1039 | vn 0.000000 -1.000000 -0.000000 1040 | vn 0.000000 -1.000000 -0.000000 1041 | vn 0.000000 -1.000000 -0.000000 1042 | vn 0.000000 -1.000000 -0.000000 1043 | vn 0.000000 -1.000000 -0.000000 1044 | vn 0.000000 0.000000 1.000000 1045 | vn 0.000000 0.000000 1.000000 1046 | vn 0.000000 0.000000 -1.000000 1047 | vn 0.000000 0.000000 -1.000000 1048 | vn 0.000000 0.000000 -1.000000 1049 | vn 0.000000 0.000000 -1.000000 1050 | vn 0.000000 0.000000 -1.000000 1051 | vn 0.000000 0.000000 -1.000000 1052 | vn 0.000000 0.000000 -1.000000 1053 | vn 0.000000 0.000000 -1.000000 1054 | vn 0.000000 0.000000 -1.000000 1055 | vn 0.000000 0.000000 -1.000000 1056 | vn 0.000000 0.000000 -1.000000 1057 | vn 0.000000 0.000000 -1.000000 1058 | vn 0.000000 0.000000 -1.000000 1059 | vn 0.000000 1.000000 0.000000 1060 | vn 0.000000 1.000000 0.000000 1061 | vn 0.000000 1.000000 0.000000 1062 | vn 0.000000 1.000000 0.000000 1063 | vn 1.000000 0.000723 0.000000 1064 | vn 1.000000 0.000723 0.000000 1065 | vn 1.000000 0.000723 0.000000 1066 | vn 1.000000 0.000723 0.000000 1067 | vn 0.000000 -1.000000 0.000000 1068 | vn 0.000000 -1.000000 0.000000 1069 | vn -0.999980 0.006393 0.000000 1070 | vn -0.999980 0.006393 0.000000 1071 | vn -0.999980 0.006393 0.000000 1072 | vn -0.999980 0.006393 0.000000 1073 | vn 0.000000 1.000000 0.000000 1074 | vn 0.000000 1.000000 0.000000 1075 | vn 1.000000 0.000723 0.000000 1076 | vn 1.000000 0.000723 0.000000 1077 | vn 1.000000 0.000723 0.000000 1078 | vn 1.000000 0.000723 0.000000 1079 | vn 0.000000 -1.000000 0.000000 1080 | vn 0.000000 -1.000000 0.000000 1081 | vn 0.000000 -1.000000 0.000000 1082 | vn 0.000000 -1.000000 0.000000 1083 | vn -0.999980 0.006394 0.000000 1084 | vn -0.999980 0.006394 0.000000 1085 | vn -0.999980 0.006394 0.000000 1086 | vn -0.999980 0.006394 0.000000 1087 | vn -0.663122 0.748511 -0.000031 1088 | vn -0.663122 0.748511 -0.000031 1089 | vn -0.663122 0.748511 -0.000031 1090 | vn -0.663122 0.748511 -0.000031 1091 | vn -0.663122 0.748511 -0.000031 1092 | vn -0.552697 -0.833382 0.000017 1093 | vn -0.552697 -0.833382 0.000017 1094 | vn -0.552697 -0.833382 0.000017 1095 | vn -0.552697 -0.833382 0.000017 1096 | vn 0.657205 0.753712 0.000070 1097 | vn 0.657205 0.753712 0.000070 1098 | vn 0.657205 0.753712 0.000070 1099 | vn 0.657205 0.753712 0.000070 1100 | vn 0.657205 0.753712 0.000070 1101 | vn -0.000001 0.000000 -1.000000 1102 | vn -0.000001 0.000000 -1.000000 1103 | vn -0.000001 0.000000 -1.000000 1104 | vn -0.000001 0.000000 -1.000000 1105 | vn -0.000001 0.000000 -1.000000 1106 | vn 0.000000 0.000000 1.000000 1107 | vn 0.000000 0.000000 1.000000 1108 | vn 0.000000 0.000000 1.000000 1109 | vn 0.000000 0.000000 1.000000 1110 | vn 0.000000 0.000000 1.000000 1111 | vn 0.000000 0.000000 1.000000 1112 | vn 0.000000 0.000000 1.000000 1113 | vn 0.000000 0.000000 1.000000 1114 | vn 0.000000 0.000000 1.000000 1115 | vn 0.000000 0.000000 -1.000000 1116 | vn 0.000000 0.000000 -1.000000 1117 | vn 0.000000 0.000000 -1.000000 1118 | vn 0.000000 0.000000 -1.000000 1119 | vn 0.621665 -0.783284 -0.000001 1120 | vn 0.621665 -0.783284 -0.000001 1121 | vn 0.621665 -0.783284 -0.000001 1122 | vn 0.621665 -0.783284 -0.000001 1123 | vn -0.659568 -0.751645 -0.000184 1124 | vn -0.659568 -0.751645 -0.000184 1125 | vn -0.659568 -0.751645 -0.000184 1126 | vn -0.659568 -0.751645 -0.000184 1127 | vn 0.664574 -0.747222 -0.000186 1128 | vn 0.664574 -0.747222 -0.000186 1129 | vn 0.664574 -0.747222 -0.000186 1130 | vn 0.664574 -0.747222 -0.000186 1131 | vn -0.943829 0.000000 0.330435 1132 | vn -0.500328 0.000000 0.865836 1133 | vn -0.500328 0.000000 0.865836 1134 | vn -0.943829 0.000000 0.330435 1135 | vn 0.166637 0.000000 0.986018 1136 | vn 0.166637 0.000000 0.986018 1137 | vn 0.831469 0.000000 0.555572 1138 | vn 0.831469 0.000000 0.555572 1139 | vn 0.979502 0.000000 -0.201434 1140 | vn 0.979502 0.000000 -0.201434 1141 | vn 0.555569 0.000000 -0.831470 1142 | vn 0.555569 0.000000 -0.831470 1143 | vn -0.203757 0.000000 -0.979022 1144 | vn -0.203757 0.000000 -0.979022 1145 | vn -0.864160 0.000000 -0.503218 1146 | vn -0.864160 0.000000 -0.503218 1147 | vn 0.000000 -1.000000 -0.000000 1148 | vn 0.000000 -1.000000 -0.000000 1149 | vn 0.000000 -1.000000 -0.000000 1150 | vn 0.000000 -1.000000 -0.000000 1151 | vn 0.000000 -1.000000 -0.000000 1152 | vn 0.000000 -1.000000 -0.000000 1153 | vn 0.000000 -1.000000 -0.000000 1154 | vn 0.000000 -1.000000 -0.000000 1155 | vn -0.000000 1.000000 0.000000 1156 | vn -0.000000 1.000000 0.000000 1157 | vn -0.000000 1.000000 0.000000 1158 | vn -0.000000 1.000000 0.000000 1159 | vn -0.000000 1.000000 0.000000 1160 | vn -0.000000 1.000000 0.000000 1161 | vn -0.000000 1.000000 0.000000 1162 | vn -0.000000 1.000000 0.000000 1163 | vn 0.000000 -0.124712 -0.992193 1164 | vn 0.000000 -0.124712 -0.992193 1165 | vn 0.000000 -0.124712 -0.992193 1166 | vn 0.000000 -0.124712 -0.992193 1167 | vn 0.000000 0.989395 -0.145253 1168 | vn 0.000000 0.989395 -0.145253 1169 | vn 0.000000 0.989395 -0.145253 1170 | vn 0.000000 0.989395 -0.145253 1171 | vn 0.000000 0.124712 0.992193 1172 | vn 0.000000 0.124712 0.992193 1173 | vn 0.000000 0.124712 0.992193 1174 | vn 0.000000 0.124712 0.992193 1175 | vn 0.000000 -0.989395 0.145253 1176 | vn 0.000000 -0.989395 0.145253 1177 | vn 0.000000 -0.989395 0.145253 1178 | vn 0.000000 -0.989395 0.145253 1179 | vn -1.000000 -0.000039 -0.000317 1180 | vn -1.000000 -0.000039 -0.000317 1181 | vn -1.000000 -0.000039 -0.000317 1182 | vn -1.000000 -0.000039 -0.000317 1183 | vn 1.000000 0.000041 0.000317 1184 | vn 1.000000 0.000041 0.000317 1185 | vn 1.000000 0.000041 0.000317 1186 | vn 1.000000 0.000041 0.000317 1187 | vn -0.943829 0.000000 0.330436 1188 | vn -0.500329 0.000000 0.865835 1189 | vn -0.500329 0.000000 0.865835 1190 | vn -0.943829 0.000000 0.330436 1191 | vn 0.166637 0.000000 0.986018 1192 | vn 0.166637 0.000000 0.986018 1193 | vn 0.831469 0.000000 0.555571 1194 | vn 0.831469 0.000000 0.555571 1195 | vn 0.979502 0.000000 -0.201434 1196 | vn 0.979502 0.000000 -0.201434 1197 | vn 0.555569 0.000000 -0.831470 1198 | vn 0.555569 0.000000 -0.831470 1199 | vn -0.203757 0.000000 -0.979021 1200 | vn -0.203757 0.000000 -0.979021 1201 | vn -0.864159 0.000000 -0.503218 1202 | vn -0.864159 0.000000 -0.503218 1203 | vn 0.000000 -1.000000 -0.000000 1204 | vn 0.000000 -1.000000 -0.000000 1205 | vn 0.000000 -1.000000 -0.000000 1206 | vn 0.000000 -1.000000 -0.000000 1207 | vn 0.000000 -1.000000 -0.000000 1208 | vn 0.000000 -1.000000 -0.000000 1209 | vn 0.000000 -1.000000 -0.000000 1210 | vn 0.000000 -1.000000 -0.000000 1211 | vn -0.000000 1.000000 0.000002 1212 | vn -0.000000 1.000000 0.000002 1213 | vn -0.000000 1.000000 0.000002 1214 | vn -0.000000 1.000000 0.000002 1215 | vn -0.000000 1.000000 0.000002 1216 | vn -0.000000 1.000000 0.000002 1217 | vn -0.000000 1.000000 0.000002 1218 | vn -0.000000 1.000000 0.000002 1219 | vn -0.000000 -0.000000 -1.000000 1220 | vn -0.000000 -0.000000 -1.000000 1221 | vn -0.000000 -0.000000 -1.000000 1222 | vn -0.000000 -0.000000 -1.000000 1223 | vn -0.000000 0.000000 -1.000000 1224 | vn -0.000000 0.000000 -1.000000 1225 | vn -0.000000 0.000000 -1.000000 1226 | vn -0.000000 0.000000 -1.000000 1227 | vn -0.000000 0.000000 -1.000000 1228 | vn -0.000000 0.000000 -1.000000 1229 | vn -0.000000 0.000000 -1.000000 1230 | vn -0.000000 0.000000 -1.000000 1231 | vn -0.000000 0.000000 -1.000000 1232 | vn 0.999991 0.004199 0.000000 1233 | vn 0.999991 0.004199 0.000000 1234 | vn 0.999991 0.004199 0.000000 1235 | vn 0.999991 0.004199 0.000000 1236 | vn 0.000000 1.000000 0.000000 1237 | vn 0.000000 1.000000 0.000000 1238 | vn 0.000000 1.000000 0.000000 1239 | vn 0.000000 1.000000 0.000000 1240 | vn -1.000000 -0.000004 0.000000 1241 | vn -1.000000 -0.000004 0.000000 1242 | vn -1.000000 -0.000004 0.000000 1243 | vn -1.000000 -0.000004 0.000000 1244 | vn 0.000592 -1.000000 0.000000 1245 | vn 0.000592 -1.000000 0.000000 1246 | vn 0.000592 -1.000000 0.000000 1247 | vn 0.000592 -1.000000 0.000000 1248 | vn 0.000000 0.000000 -1.000000 1249 | vn 0.000000 0.000000 -1.000000 1250 | vn 0.000000 0.000000 -1.000000 1251 | vn 0.000000 0.000000 -1.000000 1252 | vn 0.000000 0.000000 -1.000000 1253 | vn 0.000000 0.000000 -1.000000 1254 | vn 0.000000 0.000000 -1.000000 1255 | vn 0.000000 0.000000 -1.000000 1256 | vn 0.000000 0.000000 -1.000000 1257 | vn 0.000000 0.000000 -1.000000 1258 | vn 0.000000 0.000000 -1.000000 1259 | vn 0.000000 0.000000 -1.000000 1260 | vn 0.000000 0.000000 -1.000000 1261 | vn 0.000000 0.000000 -1.000000 1262 | vn 0.000000 0.000000 -1.000000 1263 | vn 0.000000 0.000000 -1.000000 1264 | vn 0.000000 0.000000 -1.000000 1265 | vn 0.000000 0.000000 -1.000000 1266 | vn 0.000000 0.000000 -1.000000 1267 | vn 0.000000 0.000000 -1.000000 1268 | vn 0.000000 0.000000 -1.000000 1269 | vn 0.000000 0.000000 -1.000000 1270 | vn -0.000000 0.000000 -1.000000 1271 | vn -0.000000 0.000000 -1.000000 1272 | vn -0.000000 0.000000 -1.000000 1273 | vn -0.000000 0.000000 -1.000000 1274 | vn 0.000001 0.000000 1.000000 1275 | vn 0.000001 0.000000 1.000000 1276 | vn 0.000001 0.000000 1.000000 1277 | vn 0.000001 0.000000 1.000000 1278 | vn 0.000001 0.000000 1.000000 1279 | vn 0.000000 0.000000 1.000000 1280 | vn 0.000000 0.000000 1.000000 1281 | vn 0.000000 0.000000 1.000000 1282 | vn 0.000000 0.000000 1.000000 1283 | vn 0.000000 0.000000 1.000000 1284 | vn 0.000000 0.000000 1.000000 1285 | vn 0.000001 0.000000 1.000000 1286 | vn 0.000001 0.000000 1.000000 1287 | vn 0.000001 0.000000 1.000000 1288 | vn 0.000001 0.000000 1.000000 1289 | vn 0.000001 0.000000 1.000000 1290 | vn 0.000000 -0.000000 1.000000 1291 | vn 0.000000 -0.000000 1.000000 1292 | vn 0.000000 -0.000000 1.000000 1293 | vn 0.000000 -0.000000 1.000000 1294 | vn 0.000000 -0.000000 1.000000 1295 | vn 0.000014 -1.000000 0.000000 1296 | vn 0.000014 -1.000000 0.000000 1297 | vn 0.000014 -1.000000 0.000000 1298 | vn 0.000014 -1.000000 0.000000 1299 | vn 0.999998 -0.002228 0.000000 1300 | vn 0.999998 -0.002228 0.000000 1301 | vn 0.999998 -0.002228 0.000000 1302 | vn 0.999998 -0.002228 0.000000 1303 | vn -0.999988 -0.004935 0.000000 1304 | vn -0.999988 -0.004935 0.000000 1305 | vn -0.999988 -0.004935 0.000000 1306 | vn -0.999988 -0.004935 0.000000 1307 | vn -0.000000 -0.000000 1.000000 1308 | vn -0.000000 -0.000000 1.000000 1309 | vn -0.000000 -0.000000 1.000000 1310 | vn -0.000000 -0.000000 1.000000 1311 | vn -0.000000 0.000000 1.000000 1312 | vn -0.000000 0.000000 1.000000 1313 | vn -0.000000 0.000000 1.000000 1314 | vn -0.000000 0.000000 1.000000 1315 | vn -0.000000 0.000000 1.000000 1316 | vn -0.000000 0.000000 1.000000 1317 | vn -0.000000 0.000000 1.000000 1318 | vn -0.000000 0.000000 1.000000 1319 | vn -0.000000 0.000000 1.000000 1320 | vn -0.000000 0.000000 1.000000 1321 | vn 0.000000 0.000000 1.000000 1322 | vn 0.000000 0.000000 1.000000 1323 | vn 0.000000 0.000000 1.000000 1324 | vn 0.000000 0.000000 1.000000 1325 | vn -0.000000 -1.000000 -0.000000 1326 | vn -0.000000 -1.000000 -0.000000 1327 | vn -0.000000 -1.000000 -0.000000 1328 | vn -0.000000 -1.000000 -0.000000 1329 | vn 1.000000 0.000000 0.000000 1330 | vn 1.000000 0.000000 0.000000 1331 | vn 1.000000 0.000000 0.000000 1332 | vn 1.000000 0.000000 0.000000 1333 | vn 0.000000 1.000000 0.000000 1334 | vn 0.000000 1.000000 0.000000 1335 | vn 0.000000 1.000000 0.000000 1336 | vn 0.000000 1.000000 0.000000 1337 | vn -1.000000 0.000000 0.000000 1338 | vn -1.000000 0.000000 0.000000 1339 | vn -1.000000 0.000000 0.000000 1340 | vn -1.000000 0.000000 0.000000 1341 | vn 0.000000 0.000000 1.000000 1342 | vn 0.000000 0.000000 1.000000 1343 | vn 0.000000 0.000000 1.000000 1344 | vn 0.000000 0.000000 1.000000 1345 | vn 1.000000 -0.000000 -0.000000 1346 | vn 1.000000 -0.000000 -0.000000 1347 | vn 1.000000 -0.000000 -0.000000 1348 | vn 1.000000 -0.000000 -0.000000 1349 | vn 1.000000 -0.000000 -0.000000 1350 | vn 1.000000 -0.000000 -0.000000 1351 | vn 1.000000 -0.000000 -0.000000 1352 | vn 1.000000 -0.000000 -0.000000 1353 | vn 1.000000 -0.000000 -0.000000 1354 | vn 1.000000 -0.000000 -0.000000 1355 | vn 1.000000 -0.000000 -0.000000 1356 | vn 1.000000 -0.000000 -0.000000 1357 | vn 1.000000 0.000001 0.000000 1358 | vn 1.000000 0.000001 0.000000 1359 | vn 1.000000 0.000001 0.000000 1360 | vn 1.000000 0.000001 0.000000 1361 | vn 1.000000 0.000001 0.000000 1362 | vn 1.000000 0.000001 0.000000 1363 | vn 1.000000 0.000001 0.000000 1364 | vn 1.000000 0.000001 0.000000 1365 | vn 1.000000 0.000001 0.000000 1366 | vn 1.000000 -0.000000 -0.000000 1367 | vn 1.000000 -0.000000 -0.000000 1368 | vn 1.000000 -0.000000 -0.000000 1369 | vn 1.000000 -0.000000 -0.000000 1370 | vn 1.000000 -0.000000 -0.000000 1371 | vn 1.000000 -0.000000 -0.000000 1372 | vn 1.000000 -0.000000 -0.000000 1373 | vn 1.000000 -0.000000 -0.000000 1374 | vn 0.000000 -1.000000 0.000804 1375 | vn 0.000000 -1.000000 0.000804 1376 | vn 0.000000 -1.000000 0.000804 1377 | vn 0.000000 -1.000000 0.000804 1378 | vn 0.000000 -0.006510 -0.999979 1379 | vn 0.000000 -0.006510 -0.999979 1380 | vn 0.000000 -0.006510 -0.999979 1381 | vn 0.000000 -0.006510 -0.999979 1382 | vn 0.000001 1.000000 0.001000 1383 | vn 0.000001 1.000000 0.001000 1384 | vn 0.000001 1.000000 0.001000 1385 | vn 0.000001 1.000000 0.001000 1386 | vn -0.000000 0.006560 0.999979 1387 | vn -0.000000 0.006560 0.999979 1388 | vn -0.000000 0.006560 0.999979 1389 | vn -0.000000 0.006560 0.999979 1390 | vn 0.000000 -1.000000 0.000803 1391 | vn 0.000000 -1.000000 0.000803 1392 | vn 0.000000 -1.000000 0.000803 1393 | vn 0.000000 -1.000000 0.000803 1394 | vn 0.000000 -0.006518 -0.999979 1395 | vn 0.000000 -0.006518 -0.999979 1396 | vn 0.000000 -0.006518 -0.999979 1397 | vn 0.000000 -0.006518 -0.999979 1398 | vn 0.000000 1.000000 0.001000 1399 | vn 0.000000 1.000000 0.001000 1400 | vn 0.000000 1.000000 0.001000 1401 | vn 0.000000 1.000000 0.001000 1402 | vn 0.000000 0.006490 0.999979 1403 | vn 0.000000 0.006490 0.999979 1404 | vn 0.000000 0.006490 0.999979 1405 | vn 0.000000 0.006490 0.999979 1406 | vn 1.000000 -0.000000 0.000000 1407 | vn 1.000000 -0.000000 0.000000 1408 | vn 1.000000 -0.000000 0.000000 1409 | vn 1.000000 -0.000000 0.000000 1410 | vn 1.000000 -0.000000 0.000000 1411 | vn 1.000000 -0.000000 0.000000 1412 | vn 1.000000 -0.000000 0.000000 1413 | vn 1.000000 -0.000000 0.000000 1414 | vn -1.000000 0.000000 0.000000 1415 | vn -1.000000 0.000000 0.000000 1416 | vn -1.000000 0.000000 0.000000 1417 | vn -1.000000 0.000000 0.000000 1418 | vn -1.000000 0.000000 0.000000 1419 | vn -1.000000 0.000000 0.000000 1420 | vn -1.000000 0.000000 0.000000 1421 | vn -1.000000 0.000000 0.000000 1422 | vn -1.000000 0.000000 0.000000 1423 | vn -1.000000 0.000000 0.000000 1424 | vn -1.000000 0.000000 0.000000 1425 | vn -1.000000 0.000000 0.000000 1426 | vn -1.000000 0.000000 0.000000 1427 | vn -1.000000 0.000000 0.000000 1428 | vn -1.000000 0.000000 0.000000 1429 | vn -1.000000 0.000000 0.000000 1430 | vn -1.000000 0.000000 0.000000 1431 | vn -1.000000 -0.000000 0.000000 1432 | vn -1.000000 -0.000000 0.000000 1433 | vn -1.000000 -0.000000 0.000000 1434 | vn -1.000000 -0.000000 0.000000 1435 | vn -1.000000 -0.000000 0.000000 1436 | vn -1.000000 -0.000000 0.000000 1437 | vn -1.000000 -0.000000 0.000000 1438 | vn -1.000000 -0.000000 0.000000 1439 | vn -1.000000 -0.000000 -0.000000 1440 | vn -1.000000 -0.000000 -0.000000 1441 | vn -1.000000 -0.000000 -0.000000 1442 | vn -1.000000 -0.000000 -0.000000 1443 | vn 0.000001 -0.999999 0.001114 1444 | vn 0.000001 -0.999999 0.001114 1445 | vn 0.000001 -0.999999 0.001114 1446 | vn 0.000001 -0.999999 0.001114 1447 | vn 0.000000 0.000027 1.000000 1448 | vn 0.000000 0.000027 1.000000 1449 | vn 0.000000 0.000027 1.000000 1450 | vn 0.000000 0.000027 1.000000 1451 | vn 0.000000 0.999999 0.001039 1452 | vn 0.000000 0.999999 0.001039 1453 | vn 0.000000 0.999999 0.001039 1454 | vn 0.000000 0.999999 0.001039 1455 | vn 0.000000 0.000021 -1.000000 1456 | vn 0.000000 0.000021 -1.000000 1457 | vn 0.000000 0.000021 -1.000000 1458 | vn 0.000000 0.000021 -1.000000 1459 | vn 0.000003 -0.999999 0.001113 1460 | vn 0.000003 -0.999999 0.001113 1461 | vn 0.000003 -0.999999 0.001113 1462 | vn 0.000003 -0.999999 0.001113 1463 | vn 0.000000 0.006691 0.999978 1464 | vn 0.000000 0.006691 0.999978 1465 | vn 0.000000 0.006691 0.999978 1466 | vn 0.000000 0.006691 0.999978 1467 | vn 0.000001 0.999999 0.001039 1468 | vn 0.000001 0.999999 0.001039 1469 | vn 0.000001 0.999999 0.001039 1470 | vn 0.000001 0.999999 0.001039 1471 | vn 0.000001 -0.006624 -0.999978 1472 | vn 0.000001 -0.006624 -0.999978 1473 | vn 0.000001 -0.006624 -0.999978 1474 | vn 0.000001 -0.006624 -0.999978 1475 | vn -1.000000 0.000000 0.000000 1476 | vn -1.000000 0.000000 0.000000 1477 | vn -1.000000 0.000000 0.000000 1478 | vn -1.000000 0.000000 0.000000 1479 | vn -1.000000 0.000000 0.000000 1480 | vn -1.000000 0.000000 0.000000 1481 | vn -1.000000 0.000000 0.000000 1482 | vn -1.000000 0.000000 0.000000 1483 | s off 1484 | g polySurface73 1485 | usemtl lambert13SG 1486 | f 1/1/1 2/2/2 3/3/3 4/4/4 1487 | s 1 1488 | f 14/5/5 7/6/6 5/7/7 13/8/8 17/9/9 6/10/10 8/11/11 18/12/12 1489 | s off 1490 | f 15/13/13 9/14/14 7/15/15 14/16/16 18/17/17 8/18/18 10/19/19 19/20/20 1491 | f 21/21/21 22/22/22 23/23/23 24/24/24 1492 | f 5/25/25 7/26/26 9/27/27 11/28/28 21/29/29 24/30/30 1493 | f 13/31/31 16/32/32 20/33/33 17/34/34 1494 | f 26/35/35 25/36/36 27/37/37 28/38/38 1495 | f 20/39/39 10/40/40 12/41/41 27/42/42 25/43/43 1496 | f 16/44/44 13/45/45 23/46/46 22/47/47 1497 | s 1 1498 | f 13/8/8 5/7/7 24/48/48 23/49/49 1499 | s off 1500 | f 17/50/50 20/51/51 25/52/52 26/53/53 1501 | f 6/54/54 28/55/55 27/56/56 12/57/57 10/58/58 8/59/59 1502 | s 1 1503 | f 6/10/10 17/9/9 26/60/60 28/61/61 1504 | s off 1505 | f 16/62/62 9/63/63 15/64/64 19/65/65 10/40/66 20/39/67 1506 | f 16/62/68 22/66/69 21/67/70 11/68/71 9/63/72 1507 | f 29/69/73 30/70/74 31/71/75 32/72/76 1508 | f 40/73/77 49/74/78 51/75/79 50/76/80 42/77/81 1509 | s 14 1510 | f 38/78/82 43/79/83 44/80/84 37/81/85 39/82/86 47/83/87 49/84/88 40/85/89 1511 | s off 1512 | f 37/86/90 36/87/91 41/88/92 39/89/93 1513 | f 35/90/94 36/91/95 33/92/96 46/93/97 45/94/98 34/95/99 1514 | s 17 1515 | f 35/96/100 38/97/101 40/98/102 42/99/103 1516 | s 18 1517 | f 35/100/104 42/101/105 50/102/106 48/103/107 41/104/108 36/105/109 1518 | s 17 1519 | f 35/106/100 36/107/110 37/108/111 38/109/101 1520 | s off 1521 | f 47/110/112 39/111/113 41/112/114 48/113/115 52/114/116 1522 | f 53/115/117 54/116/118 55/117/119 56/118/120 1523 | f 58/119/121 57/120/122 59/121/123 60/122/124 1524 | f 51/123/125 52/124/126 54/125/127 53/126/128 1525 | f 52/127/129 48/128/130 55/129/131 54/130/132 1526 | s 18 1527 | f 48/103/107 50/102/106 56/131/133 55/132/134 1528 | s off 1529 | f 50/133/135 51/134/136 53/135/137 56/136/138 1530 | s 14 1531 | f 49/84/88 47/83/87 57/137/139 58/138/140 1532 | s off 1533 | f 47/139/141 52/140/142 59/141/143 57/142/144 1534 | f 52/143/145 51/144/146 60/145/147 59/146/148 1535 | f 51/147/149 49/148/150 58/149/151 60/150/152 1536 | f 61/151/153 72/152/154 62/153/155 65/154/156 64/155/157 1537 | f 62/153/158 74/156/159 67/157/160 65/154/161 1538 | f 63/158/162 61/159/163 64/160/164 68/161/165 66/162/166 1539 | f 61/163/167 63/164/168 71/165/169 73/166/170 72/167/171 1540 | f 64/168/172 65/169/173 67/170/174 69/171/175 68/172/176 1541 | f 68/172/177 69/171/178 70/173/179 66/174/180 1542 | f 72/167/181 73/166/182 74/175/183 62/176/184 1543 | f 70/177/185 71/178/186 63/158/187 66/162/188 1544 | f 70/179/189 69/180/190 73/181/191 71/182/192 1545 | f 73/181/193 69/180/194 67/183/195 74/184/196 1546 | s 38 1547 | f 75/185/197 76/186/198 84/187/199 83/188/200 1548 | f 76/186/198 77/189/201 85/190/202 84/187/199 1549 | f 77/189/201 78/191/203 86/192/204 85/190/202 1550 | f 78/193/203 79/194/205 87/195/206 86/196/204 1551 | f 79/194/205 80/197/207 88/198/208 87/195/206 1552 | f 80/199/207 81/200/209 89/201/210 88/202/208 1553 | f 81/200/209 82/203/211 90/204/212 89/201/210 1554 | f 82/205/211 75/206/197 83/207/200 90/208/212 1555 | s off 1556 | f 75/209/213 82/210/214 81/211/215 80/212/216 79/213/217 78/214/218 77/215/219 76/216/220 1557 | f 83/217/221 84/218/222 85/219/223 86/220/224 87/221/225 88/222/226 89/223/227 90/224/228 1558 | f 91/225/229 92/226/230 94/227/231 93/228/232 1559 | f 93/229/233 94/230/234 96/231/235 95/232/236 1560 | f 95/233/237 96/234/238 98/235/239 97/236/240 1561 | f 97/237/241 98/238/242 92/239/243 91/240/244 1562 | f 92/241/245 98/242/246 96/243/247 94/244/248 1563 | f 97/245/249 91/246/250 93/247/251 95/248/252 1564 | s 47 1565 | f 99/249/253 100/250/254 108/251/255 107/252/256 1566 | f 100/250/254 101/253/257 109/254/258 108/251/255 1567 | f 101/253/257 102/255/259 110/256/260 109/254/258 1568 | f 102/257/259 103/258/261 111/259/262 110/260/260 1569 | f 103/258/261 104/261/263 112/262/264 111/259/262 1570 | f 104/263/263 105/264/265 113/265/266 112/266/264 1571 | f 105/264/265 106/267/267 114/268/268 113/265/266 1572 | f 106/269/267 99/270/253 107/271/256 114/272/268 1573 | s off 1574 | f 99/273/269 106/274/270 105/275/271 104/276/272 103/277/273 102/278/274 101/279/275 100/280/276 1575 | f 107/281/277 108/282/278 109/283/279 110/284/280 111/285/281 112/286/282 113/287/283 114/288/284 1576 | f 115/289/285 116/290/286 117/291/287 118/292/288 1577 | f 119/293/289 120/294/290 121/295/291 122/296/292 1578 | f 123/297/293 124/298/294 125/299/295 126/300/296 127/301/297 1579 | f 128/302/298 129/303/299 130/304/300 131/305/301 1580 | f 132/306/302 133/307/303 134/308/304 135/309/305 1581 | f 136/310/306 137/311/307 138/312/308 139/313/309 1582 | f 140/314/310 141/315/311 142/316/312 143/317/313 1583 | f 144/318/314 145/319/315 146/320/316 147/321/317 148/322/318 1584 | f 149/323/319 150/324/320 151/325/321 152/326/322 153/327/323 154/328/324 1585 | f 155/329/325 156/330/326 157/331/327 158/332/328 159/333/329 1586 | f 160/334/330 161/335/331 162/336/332 163/337/333 164/338/334 165/339/335 1587 | f 166/340/336 167/341/337 168/342/338 169/343/339 1588 | f 170/344/340 171/345/341 172/346/342 173/347/343 174/348/344 1589 | f 175/349/345 176/350/346 177/351/347 178/352/348 179/353/349 180/354/350 1590 | f 181/355/351 182/356/352 183/357/353 184/358/354 185/359/355 1591 | f 186/360/356 187/361/357 188/362/358 189/363/359 190/364/360 1592 | f 191/365/361 192/366/362 193/367/363 194/368/364 1593 | f 195/369/365 196/370/366 197/371/367 198/372/368 1594 | f 199/373/369 200/374/370 201/375/371 202/376/372 1595 | f 203/377/373 204/378/374 205/379/375 206/380/376 1596 | f 207/381/377 208/382/378 209/383/379 210/384/380 211/385/381 212/386/382 1597 | f 213/387/383 214/388/384 215/389/385 216/390/386 1598 | f 217/391/387 218/392/388 219/393/389 220/394/390 1599 | f 221/395/391 222/396/392 223/397/393 224/398/394 1600 | f 225/399/395 226/400/396 227/401/397 228/402/398 1601 | f 229/403/399 230/404/400 231/405/401 232/406/402 1602 | f 233/407/403 234/408/404 235/409/405 236/410/406 1603 | f 237/411/407 238/412/408 239/413/409 240/414/410 1604 | f 241/415/411 242/416/412 243/417/413 244/418/414 1605 | f 245/419/415 246/420/416 247/421/417 248/422/418 249/423/419 250/424/420 251/425/421 252/426/422 1606 | f 253/427/423 254/428/424 255/429/425 256/430/426 257/431/427 258/432/428 259/433/429 260/434/430 261/435/431 1607 | f 262/436/432 263/437/433 264/438/434 265/439/435 1608 | f 266/440/436 267/441/437 268/442/438 269/443/439 1609 | f 270/444/440 271/445/441 272/446/442 273/447/443 1610 | f 274/448/444 275/449/445 276/450/446 277/451/447 1611 | f 278/452/448 279/453/449 280/454/450 281/455/451 1612 | f 282/456/452 283/457/453 284/458/454 285/459/455 1613 | f 286/460/456 287/461/457 288/462/458 289/463/459 1614 | f 290/464/460 291/465/461 292/466/462 293/467/463 1615 | f 294/468/464 295/469/465 296/470/466 297/471/467 1616 | f 298/472/468 299/473/469 300/474/470 301/475/471 1617 | f 302/476/472 303/477/473 304/478/474 305/479/475 1618 | f 306/480/476 307/481/477 308/482/478 309/483/479 1619 | f 310/484/480 311/485/481 312/486/482 313/487/483 314/488/484 315/489/485 316/490/486 317/491/487 1620 | f 318/492/488 319/493/489 320/494/490 321/495/491 322/496/492 323/497/493 324/498/494 325/499/495 326/500/496 1621 | f 327/501/497 328/502/498 329/503/499 330/504/500 1622 | f 331/505/501 332/506/502 333/507/503 334/508/504 1623 | f 335/509/505 336/510/506 337/511/507 338/512/508 1624 | f 339/513/509 340/514/510 341/515/511 342/516/512 1625 | f 343/517/513 344/518/514 345/519/515 346/520/516 1626 | f 347/521/517 348/522/518 349/523/519 350/524/520 1627 | f 351/525/521 352/526/522 353/527/523 354/528/524 1628 | f 355/529/525 356/530/526 357/531/527 358/532/528 1629 | f 359/533/529 360/534/530 361/535/531 362/536/532 1630 | f 363/537/533 364/538/534 365/539/535 366/540/536 1631 | f 367/541/537 368/542/538 369/543/539 370/544/540 1632 | f 371/545/541 372/546/542 373/547/543 374/548/544 1633 | f 375/549/545 376/550/546 377/551/547 378/552/548 1634 | -------------------------------------------------------------------------------- /examples/resources/mario.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeachCraft/TeachCraft-Examples/a8b8e856843956a202d87fac96b60526e53a1b88/examples/resources/mario.gif -------------------------------------------------------------------------------- /examples/resources/shuttle.obj: -------------------------------------------------------------------------------- 1 | # Viewpoint Datalabs International, Inc. Copyright 1996 2 | 3 | 4 | mtllib ./vp.mtl 5 | 6 | g 7 | v 3.070224 -0.119728 0.996443 8 | v 5.942016 -0.012019 4.157199 9 | v 6.614015 -0.063428 4.157199 10 | v 5.759114 0.000000 1.664500 11 | v 3.070224 -0.449143 0.929434 12 | v 5.000295 -0.539011 1.315104 13 | v 3.070224 -0.604752 0.872464 14 | v 3.070224 -0.866525 0.730690 15 | v 3.070224 -0.959007 0.650256 16 | v 3.070224 -1.053631 0.163277 17 | v 2.983248 -1.080021 -0.880639 18 | v 6.130317 -1.100022 -1.106943 19 | v 3.739287 -4.334102 -0.876958 20 | v 4.400283 -4.682100 -0.952940 21 | v 3.038248 -4.334102 -0.811319 22 | v 3.180259 -4.550090 -0.921939 23 | v 2.700250 -4.334102 -0.947940 24 | v 0.840214 -2.480049 -1.050312 25 | v 1.208789 -1.060728 0.203820 26 | v 1.208789 -1.054148 0.411073 27 | v 1.208789 -0.958092 0.610367 28 | v 1.208789 -0.875165 0.685964 29 | v 1.208789 -0.621528 0.854704 30 | v 1.208789 -0.467365 0.922276 31 | v -4.649089 -1.039587 0.209476 32 | v -4.649345 -0.922345 0.432259 33 | v -4.649708 -0.652575 0.753550 34 | v -4.999902 -1.012545 0.094530 35 | v -4.999240 -0.870266 0.347384 36 | v -4.999321 -0.802315 0.416133 37 | v -4.906714 -0.620194 0.686502 38 | v -4.999759 -0.491153 0.805206 39 | v -5.568033 -0.119200 0.568687 40 | v -5.349121 -0.814175 0.247113 41 | v -5.348800 -0.938377 -0.030175 42 | v -6.499984 -0.676000 -0.433500 43 | v -6.499984 -0.610000 -0.164800 44 | v -6.499984 -0.240000 0.109600 45 | v -7.649984 0.000000 -0.620000 46 | v 1.209237 -1.080021 -1.321617 47 | v 3.070224 0.119728 0.996443 48 | v 3.093016 0.040804 1.276300 49 | v 6.614015 0.063428 4.157199 50 | v 3.070224 0.449143 0.929434 51 | v 5.000295 0.539011 1.315104 52 | v 3.070224 0.604752 0.872464 53 | v 3.070224 0.866525 0.730690 54 | v 5.000295 1.149023 1.260104 55 | v 3.070224 0.959007 0.650256 56 | v 3.070224 1.053627 0.449897 57 | v 5.000295 1.428028 0.442095 58 | v 3.070224 1.053631 0.163277 59 | v 2.983248 1.080021 -0.880639 60 | v 5.000295 1.302926 -1.259946 61 | v 3.739287 4.334102 -0.876958 62 | v 4.400283 4.682100 -0.952940 63 | v 3.038248 4.334102 -0.811319 64 | v 3.180259 4.550090 -0.921939 65 | v 1.209237 1.080021 -0.636414 66 | v 2.700250 4.334102 -0.947940 67 | v 0.169216 1.990039 -1.063281 68 | v 1.208789 1.060728 0.203820 69 | v 1.208789 1.054148 0.411073 70 | v 1.208789 0.958092 0.610367 71 | v 1.208789 0.875165 0.685964 72 | v 1.208789 0.621528 0.854704 73 | v 1.208789 0.467365 0.922276 74 | v -4.649089 1.039587 0.209476 75 | v -4.649345 0.922345 0.432259 76 | v -4.649708 0.652575 0.753550 77 | v -4.649856 0.514670 0.885149 78 | v -4.649964 0.160748 0.994500 79 | v -4.999902 1.012545 0.094530 80 | v -4.999240 0.870266 0.347384 81 | v -4.999321 0.802315 0.416133 82 | v -4.999759 0.491153 0.805206 83 | v -4.999948 0.160720 0.980689 84 | v -5.299752 0.147914 0.811038 85 | v -5.349121 0.814175 0.247113 86 | v -5.348800 0.938377 -0.030175 87 | v -6.499984 0.676000 -0.433500 88 | v -6.499931 0.693962 -0.748535 89 | v -6.499984 0.610000 -0.164800 90 | v -6.499984 0.523000 -0.048800 91 | v -6.499984 0.240000 0.109600 92 | v 1.209237 1.080021 -1.321617 93 | v -5.568033 0.119200 0.568687 94 | v -5.299752 -0.147914 0.811038 95 | v -4.999948 -0.160720 0.980689 96 | v -4.649964 -0.160748 0.994500 97 | v 1.208789 -0.130179 0.996071 98 | v 1.208789 0.130179 0.996071 99 | v 3.093016 -0.040804 1.276300 100 | v 5.942016 0.012019 4.157199 101 | v 7.043714 0.000000 4.157199 102 | v 4.998233 -0.130896 1.193100 103 | v 5.171283 -1.310384 -1.055942 104 | v 6.130317 1.100022 -1.106943 105 | v 2.983248 -1.080021 -1.351649 106 | v 2.983248 1.080021 -1.351649 107 | v -6.499931 -0.693962 -0.748535 108 | v -4.999902 -1.000020 -0.943979 109 | v 0.169216 -1.990039 -1.063281 110 | v 5.000295 -1.510030 0.750093 111 | v 5.000295 -0.874017 1.399122 112 | v 5.000295 -1.149023 1.260104 113 | v 5.000295 0.874017 1.399122 114 | v -7.074984 -0.304058 -0.264426 115 | v -7.074984 0.139529 -0.169387 116 | v -7.074984 0.304058 -0.264426 117 | v -7.074957 0.403450 -0.684268 118 | v -7.074984 0.393008 -0.495246 119 | v -7.074984 0.354637 -0.334026 120 | v -7.074984 0.057454 -0.155083 121 | v -7.074984 -0.354637 -0.334026 122 | v -7.074984 -0.393008 -0.495246 123 | v -7.074957 -0.403450 -0.684268 124 | v -7.074984 -0.139529 -0.169387 125 | v -7.074984 -0.057454 -0.155083 126 | v 5.257180 -0.244260 -0.448877 127 | v 5.275361 -0.389797 -0.446328 128 | v 5.534085 -0.255527 -0.410058 129 | v 5.858724 -0.171973 -0.364548 130 | v 6.246687 -0.127423 -0.310161 131 | v 6.245811 -0.209802 -0.310283 132 | v 5.957494 -0.242908 -0.350702 133 | v 5.684797 -0.367023 -0.388930 134 | v 5.030259 -0.310424 -0.039389 135 | v 5.218888 -0.403501 -0.175729 136 | v 5.254566 -0.476272 -0.297997 137 | v 5.497149 -0.409135 -0.146573 138 | v 5.811742 -0.367356 -0.029404 139 | v 6.194348 -0.345081 0.063191 140 | v 6.203377 -0.386271 -0.007583 141 | v 5.919040 -0.402825 -0.076394 142 | v 5.661265 -0.464884 -0.221067 143 | v 5.030257 -0.815056 -0.039376 144 | v 5.218887 -0.721987 -0.175721 145 | v 5.254566 -0.649223 -0.297993 146 | v 5.497147 -0.716354 -0.146565 147 | v 5.811740 -0.758129 -0.029394 148 | v 6.194347 -0.780403 0.063202 149 | v 6.203376 -0.739216 -0.007574 150 | v 5.919039 -0.722663 -0.076386 151 | v 5.661264 -0.660610 -0.221062 152 | v 5.533661 -0.562752 -0.410117 153 | v 5.257178 -0.881243 -0.448860 154 | v 5.275359 -0.735706 -0.446319 155 | v 5.534083 -0.869976 -0.410042 156 | v 5.858722 -0.953530 -0.364528 157 | v 6.246684 -0.998080 -0.310138 158 | v 6.245809 -0.915701 -0.310265 159 | v 5.957492 -0.882595 -0.350685 160 | v 5.684796 -0.758480 -0.388920 161 | v 5.151601 -0.815102 -0.904963 162 | v 5.295470 -0.722016 -0.722016 163 | v 5.296154 -0.649239 -0.594654 164 | v 5.571022 -0.716382 -0.673535 165 | v 5.905705 -0.758165 -0.699682 166 | v 6.299025 -0.780442 -0.683500 167 | v 6.288245 -0.739248 -0.612975 168 | v 5.995947 -0.722692 -0.625000 169 | v 5.708329 -0.660628 -0.556788 170 | v 5.295474 -0.403530 -0.722041 171 | v 5.296155 -0.476288 -0.594668 172 | v 5.571025 -0.409163 -0.673559 173 | v 5.905710 -0.367392 -0.699712 174 | v 6.299029 -0.345120 -0.683534 175 | v 6.288249 -0.386303 -0.613002 176 | v 5.995951 -0.402854 -0.625025 177 | v 5.708331 -0.464902 -0.556803 178 | v 5.218888 0.403501 -0.175729 179 | v 5.257180 0.244260 -0.448877 180 | v 5.254566 0.476272 -0.297997 181 | v 5.275361 0.389797 -0.446328 182 | v 5.497149 0.409135 -0.146573 183 | v 5.534085 0.255527 -0.410058 184 | v 5.811742 0.367356 -0.029404 185 | v 5.858724 0.171973 -0.364548 186 | v 6.194348 0.345081 0.063191 187 | v 6.246687 0.127423 -0.310161 188 | v 6.203377 0.386271 -0.007583 189 | v 6.245811 0.209802 -0.310283 190 | v 5.919040 0.402825 -0.076394 191 | v 5.957494 0.242908 -0.350702 192 | v 5.661265 0.464884 -0.221067 193 | v 5.684797 0.367023 -0.388930 194 | v 5.218887 0.721987 -0.175721 195 | v 5.254566 0.649223 -0.297993 196 | v 5.497147 0.716354 -0.146565 197 | v 5.811740 0.758129 -0.029394 198 | v 6.194347 0.780403 0.063202 199 | v 6.203376 0.739216 -0.007574 200 | v 5.919039 0.722663 -0.076386 201 | v 5.661264 0.660610 -0.221062 202 | v 5.257178 0.881243 -0.448860 203 | v 5.275359 0.735706 -0.446319 204 | v 5.534083 0.869976 -0.410042 205 | v 5.858722 0.953530 -0.364528 206 | v 6.246684 0.998080 -0.310138 207 | v 6.245809 0.915701 -0.310265 208 | v 5.957492 0.882595 -0.350685 209 | v 5.684796 0.758480 -0.388920 210 | v 5.533661 0.562752 -0.410117 211 | v 5.295470 0.722016 -0.722016 212 | v 5.296154 0.649239 -0.594654 213 | v 5.571022 0.716382 -0.673535 214 | v 5.905705 0.758165 -0.699682 215 | v 6.299025 0.780442 -0.683500 216 | v 6.288245 0.739248 -0.612975 217 | v 5.995947 0.722692 -0.625000 218 | v 5.708329 0.660628 -0.556788 219 | v 5.295474 0.403530 -0.722041 220 | v 5.296155 0.476288 -0.594668 221 | v 5.571025 0.409163 -0.673559 222 | v 5.905710 0.367392 -0.699712 223 | v 6.299029 0.345120 -0.683534 224 | v 6.288249 0.386303 -0.613002 225 | v 5.995951 0.402854 -0.625025 226 | v 5.708331 0.464902 -0.556803 227 | v 5.165639 -0.318491 0.637328 228 | v 5.166101 -0.159250 0.913146 229 | v 4.998497 -0.252327 1.074635 230 | v 5.183997 -0.172954 0.637297 231 | v 5.184248 -0.086480 0.787078 232 | v 5.445252 -0.307224 0.636859 233 | v 5.445698 -0.153617 0.902920 234 | v 5.773065 -0.390779 0.636310 235 | v 5.773632 -0.195395 0.974730 236 | v 6.164821 -0.435329 0.635652 237 | v 6.165453 -0.217671 1.012654 238 | v 6.163937 -0.352950 0.635654 239 | v 6.164450 -0.176480 0.941314 240 | v 5.872800 -0.319843 0.636142 241 | v 5.873264 -0.159926 0.913131 242 | v 5.597437 -0.195729 0.636604 243 | v 5.597722 -0.097867 0.806108 244 | v 5.444824 0.000000 0.636860 245 | v 5.166102 0.159236 0.913155 246 | v 5.184248 0.086472 0.787083 247 | v 5.445698 0.153603 0.902928 248 | v 5.773632 0.195378 0.974740 249 | v 6.165453 0.217651 1.012665 250 | v 6.164450 0.176464 0.941323 251 | v 5.873265 0.159912 0.913140 252 | v 5.597722 0.097858 0.806113 253 | v 5.165639 0.318491 0.637345 254 | v 4.997765 0.504639 0.637636 255 | v 5.183997 0.172954 0.637307 256 | v 5.445252 0.307224 0.636875 257 | v 5.773065 0.390779 0.636330 258 | v 6.164821 0.435329 0.635675 259 | v 6.163937 0.352950 0.635673 260 | v 5.872800 0.319843 0.636159 261 | v 5.597437 0.195729 0.636614 262 | v 5.165176 0.159265 0.361518 263 | v 4.997031 0.252350 0.200598 264 | v 5.183746 0.086488 0.487521 265 | v 5.444806 0.153631 0.370806 266 | v 5.772497 0.195413 0.297899 267 | v 6.164188 0.217691 0.258662 268 | v 6.163424 0.176496 0.330003 269 | v 5.872335 0.159941 0.359162 270 | v 5.597153 0.097876 0.467105 271 | v 5.165176 -0.159221 0.361493 272 | v 4.997031 -0.252281 0.200558 273 | v 5.183746 -0.086464 0.487507 274 | v 5.444806 -0.153589 0.370782 275 | v 5.772497 -0.195360 0.297868 276 | v 6.164188 -0.217631 0.258628 277 | v 6.163424 -0.176448 0.329975 278 | v 5.872335 -0.159897 0.359136 279 | v 5.597153 -0.097850 0.467090 280 | v 5.090927 -1.067391 -0.472156 281 | v 5.171283 1.310384 -1.055942 282 | v 5.151606 0.310470 -0.905003 283 | v 5.151606 -0.310470 -0.905003 284 | v 5.030257 0.815056 -0.039376 285 | v 5.030259 0.310424 -0.039389 286 | v 5.090930 -0.058113 -0.472183 287 | v 5.090930 0.058113 -0.472183 288 | v 5.000295 -1.210004 0.173074 289 | v 5.000295 1.210004 0.173074 290 | v 5.000295 -1.428028 0.442095 291 | v 4.997764 -0.504639 0.637610 292 | v 4.998497 0.252304 1.074648 293 | v 4.998233 0.130896 1.193100 294 | v 5.000295 1.510030 0.750093 295 | v 5.151601 0.815102 -0.904963 296 | v 5.090927 1.067391 -0.472156 297 | v 3.070224 -1.053627 0.449897 298 | v -5.349205 0.737229 0.323968 299 | v -5.349205 -0.737229 0.323968 300 | v -5.349476 -0.470935 0.566062 301 | v -6.499984 -0.098825 0.133439 302 | v -6.499984 0.098825 0.133439 303 | v -6.499984 -0.523000 -0.048800 304 | v -5.349476 0.470935 0.566062 305 | v -4.999902 1.000020 -0.943979 306 | v 0.840214 2.480049 -1.050312 307 | v 1.209237 -1.080021 -0.636414 308 | v 3.804262 4.682100 -0.938960 309 | v 5.000295 -1.302926 -1.259946 310 | v 3.804262 -4.682100 -0.938960 311 | v -4.649856 -0.514670 0.885149 312 | v -4.999492 0.681710 0.569242 313 | v -4.649417 0.860391 0.497003 314 | v -4.906714 0.620194 0.686502 315 | v -4.649417 -0.860391 0.497003 316 | v -4.999492 -0.681710 0.569242 317 | # 310 vertices 318 | 319 | # 0 vertex parms 320 | 321 | # 0 texture vertices 322 | 323 | # 0 normals 324 | 325 | g windows 326 | usemtl glass 327 | s 1 328 | f 310 32 294 329 | f 76 308 306 330 | f 294 88 33 331 | f 310 31 32 332 | f 88 294 32 333 | f 87 33 88 78 334 | f 87 78 298 335 | f 298 76 306 336 | f 298 78 76 337 | g tail 338 | usemtl bone 339 | s 4 340 | f 95 3 96 4 341 | f 4 287 43 95 342 | f 94 2 3 43 343 | f 3 2 93 96 344 | f 41 1 93 42 345 | f 41 42 287 346 | f 43 3 95 347 | f 287 42 94 43 348 | f 42 93 2 94 349 | f 96 93 1 350 | g rearbody 351 | s 6 352 | f 275 98 54 353 | f 96 223 286 287 354 | f 97 277 155 355 | f 276 281 280 277 356 | f 276 275 289 357 | f 283 282 128 279 358 | f 283 290 275 359 | f 257 51 248 360 | f 282 303 97 361 | f 96 6 106 362 | f 303 12 97 363 | f 104 285 223 364 | f 97 155 274 365 | f 284 282 266 366 | f 286 288 287 367 | f 137 128 282 368 | f 283 279 278 369 | f 248 288 286 370 | f 6 105 106 371 | f 275 54 283 372 | f 284 266 285 373 | f 96 287 4 374 | f 284 285 104 375 | f 248 51 288 376 | f 283 278 290 377 | f 274 137 282 378 | f 289 275 290 379 | f 97 12 98 275 380 | f 48 107 45 381 | f 96 106 104 382 | f 282 283 257 266 383 | f 97 275 276 277 384 | f 104 223 96 385 | f 257 283 51 386 | f 97 274 282 387 | f 128 280 281 279 388 | f 287 288 48 389 | f 287 48 45 390 | g body 391 | s 7 392 | f 309 31 310 393 | f 294 33 295 394 | f 108 118 39 395 | f 80 79 74 73 396 | f 49 47 48 397 | f 5 1 91 24 398 | f 10 291 20 19 399 | f 294 295 38 400 | f 78 77 76 401 | f 81 82 111 112 402 | f 65 66 46 47 403 | f 30 309 310 404 | f 5 105 6 405 | f 30 29 26 309 406 | f 68 62 59 299 407 | f 78 88 89 77 408 | f 118 38 295 119 409 | f 83 81 112 113 410 | f 64 65 47 49 411 | f 35 37 36 412 | f 23 8 7 413 | f 24 91 90 305 414 | f 62 52 53 59 415 | f 296 85 109 114 416 | f 79 292 75 74 417 | f 50 49 288 418 | f 22 23 27 419 | f 282 10 11 303 420 | f 293 294 297 421 | f 71 72 92 67 422 | f 112 39 113 423 | f 310 294 293 424 | f 305 90 89 425 | f 308 70 307 426 | f 296 87 298 427 | f 114 39 119 428 | f 71 77 72 429 | f 45 107 44 430 | f 8 23 22 431 | f 7 5 24 23 432 | f 287 44 41 433 | f 307 69 74 75 434 | f 92 91 1 41 435 | f 63 62 68 436 | f 28 29 34 35 437 | f 105 7 8 106 438 | f 32 89 88 439 | f 49 48 288 440 | f 82 81 299 441 | f 115 37 297 108 442 | f 113 39 110 443 | f 73 74 69 68 444 | f 29 30 293 34 445 | f 291 104 9 446 | f 22 27 309 447 | f 54 53 52 283 448 | f 83 79 80 449 | f 83 80 81 450 | f 48 47 46 107 451 | f 25 20 21 26 452 | f 301 11 10 19 453 | f 39 115 108 454 | f 306 307 75 455 | f 110 39 109 456 | f 292 298 306 457 | f 306 308 307 458 | f 70 66 65 459 | f 294 38 297 460 | f 5 6 96 461 | f 85 84 110 109 462 | f 62 63 50 52 463 | f 102 25 28 464 | f 9 106 8 465 | f 310 293 30 466 | f 70 71 66 467 | f 77 89 90 72 468 | f 66 71 67 469 | f 297 37 34 293 470 | f 106 9 104 471 | f 25 19 20 472 | f 44 107 46 473 | f 85 296 298 474 | f 117 101 36 116 475 | f 111 39 112 476 | f 307 70 65 477 | f 35 34 37 478 | f 23 305 27 479 | f 102 301 19 25 480 | f 50 288 51 481 | f 80 73 299 482 | f 84 298 292 483 | f 49 50 63 64 484 | f 32 305 89 485 | f 1 5 96 486 | f 32 31 27 305 487 | f 66 67 44 46 488 | f 296 295 33 87 489 | f 291 10 282 490 | f 81 80 299 491 | f 309 27 31 492 | f 84 85 298 493 | f 116 36 37 115 494 | f 292 79 83 84 495 | f 283 52 51 496 | f 309 26 21 22 497 | f 284 291 282 498 | f 102 36 101 499 | f 65 64 69 307 500 | f 295 296 114 119 501 | f 73 68 299 502 | f 39 116 115 503 | f 105 5 7 504 | f 23 24 305 505 | f 39 117 116 506 | f 77 71 76 507 | f 109 39 114 508 | f 297 38 118 108 509 | f 75 292 306 510 | f 39 118 119 511 | f 21 20 291 9 512 | f 9 8 22 21 513 | f 287 45 44 514 | f 71 70 308 76 515 | f 84 83 113 110 516 | f 67 92 41 44 517 | f 25 26 29 28 518 | f 104 291 284 519 | f 102 28 35 520 | f 69 64 63 68 521 | f 72 90 91 92 522 | f 52 50 51 523 | f 102 35 36 524 | g wings 525 | s 5 526 | f 16 15 17 527 | f 304 15 16 528 | f 300 57 60 529 | f 14 13 304 530 | f 59 53 55 57 531 | f 60 57 58 532 | f 18 301 103 533 | f 300 59 57 534 | f 304 13 15 535 | f 56 55 53 54 536 | f 15 13 11 301 537 | f 61 59 300 538 | f 57 55 302 539 | f 103 301 102 540 | f 17 15 301 541 | f 303 11 13 14 542 | f 58 57 302 543 | f 302 55 56 544 | f 17 301 18 545 | f 299 59 61 546 | g tiles 547 | usemtl fldkdkgrey 548 | s 3 549 | f 302 56 54 550 | f 18 103 40 551 | f 16 17 99 552 | f 86 61 300 553 | f 99 304 16 554 | f 303 14 304 555 | f 99 303 304 556 | f 17 18 99 557 | f 302 54 100 558 | f 58 302 100 559 | f 100 86 300 560 | f 18 40 99 561 | f 100 60 58 562 | f 100 300 60 563 | f 101 117 111 82 564 | f 102 101 82 299 565 | f 117 39 111 566 | f 99 100 54 303 567 | f 303 54 98 12 568 | f 86 100 99 40 569 | f 40 103 61 86 570 | f 299 61 103 102 571 | g enginside 572 | usemtl redbrick 573 | s 9 574 | f 238 255 246 575 | f 194 202 201 193 576 | f 153 162 163 154 577 | f 144 153 154 145 578 | f 184 194 193 182 579 | f 238 246 237 580 | f 272 234 232 271 581 | f 236 237 235 234 582 | f 204 195 186 583 | f 134 143 144 135 584 | f 143 152 153 144 585 | f 204 203 195 586 | f 237 246 245 235 587 | f 273 236 234 272 588 | f 238 237 236 589 | f 185 184 182 183 590 | f 135 144 145 136 591 | f 154 163 146 592 | f 195 203 202 194 593 | f 235 245 244 233 594 | f 264 273 272 263 595 | f 219 185 183 218 596 | f 187 186 184 185 597 | f 136 145 146 598 | f 161 169 170 162 599 | f 204 220 212 600 | f 255 264 263 254 601 | f 234 235 233 232 602 | f 186 195 194 184 603 | f 145 154 146 604 | f 152 161 162 153 605 | f 204 212 203 606 | f 246 255 254 245 607 | f 238 236 273 608 | f 204 187 220 609 | f 169 125 126 170 610 | f 126 135 136 127 611 | f 163 171 146 612 | f 203 212 211 202 613 | f 245 254 253 244 614 | f 238 273 264 615 | f 211 219 218 210 616 | f 170 126 127 171 617 | f 127 136 146 618 | f 162 170 171 163 619 | f 202 211 210 201 620 | f 238 264 255 621 | f 254 263 262 253 622 | f 212 220 219 211 623 | f 171 127 146 624 | f 125 134 135 126 625 | f 204 186 187 626 | f 220 187 185 219 627 | f 263 272 271 262 628 | g engout 629 | usemtl black 630 | f 251 260 259 250 631 | f 209 217 216 208 632 | f 157 165 166 158 633 | f 132 141 142 133 634 | f 179 178 176 177 635 | f 215 177 175 214 636 | f 270 230 228 269 637 | f 227 241 240 225 638 | f 191 199 198 190 639 | f 150 159 160 151 640 | f 131 140 141 132 641 | f 177 176 174 175 642 | f 230 231 229 228 643 | f 269 228 226 268 644 | f 229 242 241 227 645 | f 192 200 199 191 646 | f 139 148 149 140 647 | f 130 139 140 131 648 | f 180 192 191 178 649 | f 228 229 227 226 650 | f 268 226 224 267 651 | f 231 243 242 229 652 | f 176 190 189 174 653 | f 140 149 150 141 654 | f 149 158 159 150 655 | f 190 198 197 189 656 | f 243 252 251 242 657 | f 259 268 267 258 658 | f 216 179 177 215 659 | f 181 180 178 179 660 | f 121 130 131 122 661 | f 167 123 124 168 662 | f 208 216 215 207 663 | f 250 259 258 249 664 | f 252 261 260 251 665 | f 198 207 206 197 666 | f 158 166 167 159 667 | f 123 132 133 124 668 | f 166 122 123 167 669 | f 207 215 214 206 670 | f 261 270 269 260 671 | f 241 250 249 240 672 | f 199 208 207 198 673 | f 159 167 168 160 674 | f 122 131 132 123 675 | f 165 121 122 166 676 | f 217 181 179 216 677 | f 260 269 268 259 678 | f 242 251 250 241 679 | f 200 209 208 199 680 | f 148 157 158 149 681 | f 141 150 151 142 682 | f 178 191 190 176 683 | f 226 227 225 224 684 | g engmount 685 | usemtl brass 686 | s 11 687 | f 225 240 239 222 688 | f 164 120 121 165 689 | f 128 137 138 129 690 | f 196 205 289 290 691 | f 265 221 285 266 692 | f 206 214 213 205 693 | f 138 147 148 139 694 | f 174 189 188 172 695 | f 249 258 256 247 696 | f 221 222 223 285 697 | f 155 277 164 156 698 | f 274 155 156 147 699 | f 213 173 281 276 700 | f 258 267 265 256 701 | f 189 197 196 188 702 | f 120 129 130 121 703 | f 173 172 279 281 704 | f 239 247 248 286 705 | f 205 213 276 289 706 | f 137 274 147 138 707 | f 156 164 165 157 708 | f 224 225 222 221 709 | f 247 256 257 248 710 | f 172 188 278 279 711 | f 280 128 129 120 712 | f 188 196 290 278 713 | f 256 265 266 257 714 | f 214 175 173 213 715 | f 147 156 157 148 716 | f 175 174 172 173 717 | f 240 249 247 239 718 | f 222 239 286 223 719 | f 277 280 120 164 720 | f 129 138 139 130 721 | f 197 206 205 196 722 | f 267 224 221 265 723 | g engrim 724 | usemtl dkdkgrey 725 | s off 726 | f 233 244 243 231 727 | f 124 133 134 125 728 | f 262 271 270 261 729 | f 142 151 152 143 730 | f 253 262 261 252 731 | f 151 160 161 152 732 | f 244 253 252 243 733 | f 160 168 169 161 734 | f 201 210 209 200 735 | f 271 232 230 270 736 | f 133 142 143 134 737 | f 232 233 231 230 738 | f 183 182 180 181 739 | f 218 183 181 217 740 | f 182 193 192 180 741 | f 210 218 217 209 742 | f 193 201 200 192 743 | f 168 124 125 169 744 | # 393 elements -------------------------------------------------------------------------------- /examples/turtle_3dfractaltree.py: -------------------------------------------------------------------------------- 1 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 2 | import os.path, sys 3 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 4 | 5 | # Minecraft Turtle Example 6 | from minecraftstuff import MinecraftTurtle 7 | from mcpi import minecraft 8 | from mcpi import block 9 | 10 | 11 | def tree(branchLen, t): 12 | if branchLen > 6: 13 | if branchLen > 10: 14 | t.penblock(block.WOOD) 15 | else: 16 | t.penblock(block.LEAVES) 17 | 18 | # for performance 19 | x, y, z = t.position.x, t.position.y, t.position.z 20 | # draw branch 21 | t.forward(branchLen) 22 | 23 | t.up(20) 24 | tree(branchLen - 2, t) 25 | 26 | t.right(90) 27 | tree(branchLen - 2, t) 28 | 29 | t.left(180) 30 | tree(branchLen - 2, t) 31 | 32 | t.down(40) 33 | t.right(90) 34 | tree(branchLen - 2, t) 35 | 36 | t.up(20) 37 | 38 | # go back 39 | # t.backward(branchLen) 40 | # for performance - rather than going back over every line 41 | t.setposition(x, y, z) 42 | 43 | # Connect to minecraft server 127.0.0.1 as player 'steve' 44 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 45 | 46 | # get players position 47 | pos = mc.player.getPos() 48 | 49 | # create minecraft turtle 50 | turtle = MinecraftTurtle(mc, pos) 51 | 52 | # point up 53 | turtle.setverticalheading(90) 54 | 55 | # set speed 56 | turtle.speed(0) 57 | 58 | # call the tree fractal 59 | tree(20, turtle) 60 | -------------------------------------------------------------------------------- /examples/turtle_3dfractaltree_colors.py: -------------------------------------------------------------------------------- 1 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 2 | import os.path, sys 3 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 4 | 5 | # Minecraft Turtle Example 6 | from minecraftstuff import MinecraftTurtle 7 | from mcpi import minecraft 8 | from mcpi import block 9 | import random 10 | 11 | 12 | def tree(branchLen, t): 13 | if branchLen > 6: 14 | t.penblock(block.WOOL.id, random.randint(0, 15)) 15 | 16 | # for performance 17 | x, y, z = t.position.x, t.position.y, t.position.z 18 | # draw branch 19 | t.forward(branchLen) 20 | 21 | t.up(20) 22 | tree(branchLen - 2, t) 23 | 24 | t.right(90) 25 | tree(branchLen - 2, t) 26 | 27 | t.left(180) 28 | tree(branchLen - 2, t) 29 | 30 | t.down(40) 31 | t.right(90) 32 | tree(branchLen - 2, t) 33 | 34 | t.up(20) 35 | 36 | # go back 37 | # t.backward(branchLen) 38 | # for performance - rather than going back over every line 39 | t.setposition(x, y, z) 40 | 41 | # Connect to minecraft server 127.0.0.1 as player 'steve' 42 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 43 | 44 | # get players position 45 | pos = mc.player.getPos() 46 | 47 | # create minecraft turtle 48 | turtle = MinecraftTurtle(mc, pos) 49 | 50 | # point up 51 | turtle.setverticalheading(90) 52 | 53 | # set speed 54 | turtle.speed(0) 55 | 56 | # call the tree fractal 57 | tree(20, turtle) 58 | -------------------------------------------------------------------------------- /examples/turtle_3dnautilus.py: -------------------------------------------------------------------------------- 1 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 2 | import os.path, sys 3 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 4 | 5 | # Minecraft Turtle Example 6 | from minecraftstuff import MinecraftTurtle 7 | from mcpi import minecraft 8 | from mcpi import block 9 | 10 | # Connect to minecraft server 127.0.0.1 as player 'steve' 11 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 12 | 13 | # get players position 14 | pos = mc.player.getPos() 15 | 16 | # create minecraft turtle 17 | turtle = MinecraftTurtle(mc, pos) 18 | 19 | turtle.speed(0) 20 | turtle.penblock(block.WOOL.id, 14) 21 | S = 50 22 | for j in range(0, 20): 23 | turtle.up(j * 10) 24 | turtle.forward(S) 25 | 26 | turtle.left(90) 27 | turtle.down(j * 10) 28 | turtle.forward(S) 29 | 30 | turtle.left(90) 31 | turtle.down(j * 10) 32 | turtle.forward(S) 33 | 34 | turtle.left(90) 35 | turtle.up(j * 10) 36 | turtle.forward(S) 37 | turtle.left(90) 38 | 39 | turtle.left(10) 40 | S = 0.9 * S 41 | -------------------------------------------------------------------------------- /examples/turtle_adventuresinrpi.py: -------------------------------------------------------------------------------- 1 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 2 | import os.path, sys 3 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 4 | 5 | # Minecraft Turtle Example 6 | # Ported from the scratch turtle project in "Adventures in Raspberry Pi" 7 | from minecraftstuff import MinecraftTurtle 8 | from mcpi import minecraft 9 | from mcpi import block 10 | 11 | # Connect to minecraft server 127.0.0.1 as player 'steve' 12 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 13 | 14 | # get players position 15 | pos = mc.player.getPos() 16 | 17 | # create minecraft turtle 18 | turtle = MinecraftTurtle(mc, pos) 19 | turtle.speed(0) 20 | turtle.setheading(90) 21 | NumberOfSides = 5 22 | Angle = 360 / NumberOfSides 23 | SideLength = 20 24 | WoolColour = 0 25 | 26 | for count in range(24): 27 | for side in range(NumberOfSides): 28 | turtle.forward(SideLength) 29 | turtle.right(Angle) 30 | turtle.right(15) 31 | WoolColour += 1 32 | if WoolColour > 15: 33 | WoolColour = 0 34 | turtle.penblock(block.WOOL.id, WoolColour) 35 | # go 3d 36 | # turtle.sety(turtle.position.y + 1) 37 | -------------------------------------------------------------------------------- /examples/turtle_circle.py: -------------------------------------------------------------------------------- 1 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 2 | import os.path, sys 3 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 4 | 5 | #Minecraft Turtle Example - Circle 6 | from minecraftstuff import MinecraftTurtle 7 | from mcpi import minecraft 8 | 9 | # Connect to minecraft server 127.0.0.1 as player 'steve' 10 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 11 | 12 | # get players position 13 | pos = mc.player.getPos() 14 | 15 | # create minecraft turtle 16 | turtle = MinecraftTurtle(mc, pos) 17 | turtle.speed(10) 18 | for step in range(0, 100): 19 | turtle.right(5) 20 | turtle.forward(2) 21 | -------------------------------------------------------------------------------- /examples/turtle_fractaltree.py: -------------------------------------------------------------------------------- 1 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 2 | import os.path, sys 3 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 4 | 5 | # Minecraft Turtle Example 6 | from minecraftstuff import MinecraftTurtle 7 | from mcpi import minecraft 8 | 9 | 10 | def tree(branchLen, t): 11 | if branchLen > 2: 12 | t.forward(branchLen) 13 | t.up(20) 14 | tree(branchLen - 2, t) 15 | t.down(40) 16 | tree(branchLen - 2, t) 17 | t.up(20) 18 | t.backward(branchLen) 19 | 20 | # Connect to minecraft server 127.0.0.1 as player 'steve' 21 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 22 | 23 | # get players position 24 | pos = mc.player.getPos() 25 | 26 | # create minecraft turtle 27 | turtle = MinecraftTurtle(mc, pos) 28 | 29 | # point up 30 | turtle.setverticalheading(90) 31 | 32 | # set speed 33 | turtle.speed(0) 34 | 35 | # call the tree fractal 36 | tree(20, turtle) 37 | -------------------------------------------------------------------------------- /examples/turtle_pattern.py: -------------------------------------------------------------------------------- 1 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 2 | import os.path, sys 3 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 4 | 5 | # Minecraft Turtle Example - Crazy Pattern 6 | from minecraftstuff import MinecraftTurtle 7 | from mcpi import minecraft 8 | from mcpi import block 9 | 10 | # Connect to minecraft server 127.0.0.1 as player 'steve' 11 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 12 | 13 | # get players position 14 | pos = mc.player.getPos() 15 | 16 | # create minecraft turtle 17 | turtle = MinecraftTurtle(mc, pos) 18 | 19 | turtle.penblock(block.WOOL.id, 11) 20 | turtle.speed(10) 21 | 22 | for step in range(0, 50): 23 | turtle.forward(50) 24 | turtle.right(123) 25 | -------------------------------------------------------------------------------- /examples/turtle_spiral.py: -------------------------------------------------------------------------------- 1 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 2 | import os.path, sys 3 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 4 | 5 | #Minecraft Turtle Example - Spiral 6 | from minecraftstuff import MinecraftTurtle 7 | from mcpi import minecraft 8 | from mcpi import block 9 | 10 | # Connect to minecraft server 127.0.0.1 as player 'steve' 11 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 12 | 13 | # get players position 14 | pos = mc.player.getPos() 15 | 16 | # create minecraft turtle 17 | turtle = MinecraftTurtle(mc, pos) 18 | 19 | turtle.penblock(block.WOOL.id, 11) 20 | turtle.speed(10) 21 | turtle.up(5) 22 | 23 | for step in range(0, 1000): 24 | turtle.forward(2) 25 | turtle.right(10) 26 | -------------------------------------------------------------------------------- /examples/turtle_squares.py: -------------------------------------------------------------------------------- 1 | # These two lines are because of the folder the demos are located in, and aren't normally necessary 2 | import os.path, sys 3 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 4 | 5 | # Minecraft Turtle Example 6 | from minecraftstuff import MinecraftTurtle 7 | from mcpi import minecraft 8 | 9 | # Connect to minecraft server 127.0.0.1 as player 'steve' 10 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 11 | 12 | # get players position 13 | pos = mc.player.getPos() 14 | 15 | # create minecraft turtle 16 | turtle = MinecraftTurtle(mc, pos) 17 | 18 | turtle.speed(10) 19 | 20 | # draw a square 21 | turtle.forward(10) 22 | turtle.right(90) 23 | turtle.forward(10) 24 | turtle.right(90) 25 | turtle.forward(10) 26 | turtle.right(90) 27 | turtle.forward(10) 28 | 29 | # draw a square on the floor 30 | turtle.walk() 31 | turtle.forward(11) 32 | turtle.right(90) 33 | turtle.forward(10) 34 | turtle.right(90) 35 | turtle.forward(10) 36 | turtle.right(90) 37 | turtle.forward(10) 38 | -------------------------------------------------------------------------------- /lesson1_setup.py: -------------------------------------------------------------------------------- 1 | # This setup is for http://teachcraft.net/lesson1 2 | # You must change the IP address and your name in the create() call below before running! 3 | 4 | from mcpi import minecraft 5 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 6 | 7 | y = mc.getHeight(0, 0) 8 | mc.setBlocks(-4, y-1, -4, 4, y+1, 4, 7) 9 | mc.setBlocks(-3, y, -3, 3, y+20, 3, 0) 10 | print('In your Server console, please run the following command:') 11 | print('\tsetworldspawn 0 ' + str(y) + ' 0') 12 | -------------------------------------------------------------------------------- /mcpi/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeachCraft/TeachCraft-Examples/a8b8e856843956a202d87fac96b60526e53a1b88/mcpi/__init__.py -------------------------------------------------------------------------------- /mcpi/block.py: -------------------------------------------------------------------------------- 1 | class Block: 2 | """Minecraft PI block description. Can be sent to Minecraft.setBlock/s""" 3 | def __init__(self, id, data=0): 4 | self.id = id 5 | self.data = data 6 | 7 | def __cmp__(self, rhs): 8 | return hash(self) - hash(rhs) 9 | 10 | def __hash__(self): 11 | return (self.id << 8) + self.data 12 | 13 | def withData(self, data): 14 | return Block(self.id, data) 15 | 16 | def __iter__(self): 17 | """Allows a Block to be sent whenever id [and data] is needed""" 18 | return iter((self.id, self.data)) 19 | 20 | def __repr__(self): 21 | return "Block(%d, %d)"%(self.id, self.data) 22 | 23 | AIR = Block(0) 24 | STONE = Block(1) 25 | GRASS = Block(2) 26 | DIRT = Block(3) 27 | COBBLESTONE = Block(4) 28 | WOOD_PLANKS = Block(5) 29 | SAPLING = Block(6) 30 | BEDROCK = Block(7) 31 | WATER_FLOWING = Block(8) 32 | WATER = WATER_FLOWING 33 | WATER_STATIONARY = Block(9) 34 | LAVA_FLOWING = Block(10) 35 | LAVA = LAVA_FLOWING 36 | LAVA_STATIONARY = Block(11) 37 | SAND = Block(12) 38 | GRAVEL = Block(13) 39 | GOLD_ORE = Block(14) 40 | IRON_ORE = Block(15) 41 | COAL_ORE = Block(16) 42 | WOOD = Block(17) 43 | LEAVES = Block(18) 44 | GLASS = Block(20) 45 | LAPIS_LAZULI_ORE = Block(21) 46 | LAPIS_LAZULI_BLOCK = Block(22) 47 | SANDSTONE = Block(24) 48 | BED = Block(26) 49 | COBWEB = Block(30) 50 | GRASS_TALL = Block(31) 51 | WOOL = Block(35) 52 | FLOWER_YELLOW = Block(37) 53 | FLOWER_CYAN = Block(38) 54 | MUSHROOM_BROWN = Block(39) 55 | MUSHROOM_RED = Block(40) 56 | GOLD_BLOCK = Block(41) 57 | IRON_BLOCK = Block(42) 58 | STONE_SLAB_DOUBLE = Block(43) 59 | STONE_SLAB = Block(44) 60 | BRICK_BLOCK = Block(45) 61 | TNT = Block(46) 62 | BOOKSHELF = Block(47) 63 | MOSS_STONE = Block(48) 64 | OBSIDIAN = Block(49) 65 | TORCH = Block(50) 66 | FIRE = Block(51) 67 | STAIRS_WOOD = Block(53) 68 | CHEST = Block(54) 69 | DIAMOND_ORE = Block(56) 70 | DIAMOND_BLOCK = Block(57) 71 | CRAFTING_TABLE = Block(58) 72 | FARMLAND = Block(60) 73 | FURNACE_INACTIVE = Block(61) 74 | FURNACE_ACTIVE = Block(62) 75 | DOOR_WOOD = Block(64) 76 | LADDER = Block(65) 77 | STAIRS_COBBLESTONE = Block(67) 78 | DOOR_IRON = Block(71) 79 | REDSTONE_ORE = Block(73) 80 | SNOW = Block(78) 81 | ICE = Block(79) 82 | SNOW_BLOCK = Block(80) 83 | CACTUS = Block(81) 84 | CLAY = Block(82) 85 | SUGAR_CANE = Block(83) 86 | FENCE = Block(85) 87 | GLOWSTONE_BLOCK = Block(89) 88 | BEDROCK_INVISIBLE = Block(95) 89 | STONE_BRICK = Block(98) 90 | GLASS_PANE = Block(102) 91 | MELON = Block(103) 92 | FENCE_GATE = Block(107) 93 | GLOWING_OBSIDIAN = Block(246) 94 | NETHER_REACTOR_CORE = Block(247) 95 | -------------------------------------------------------------------------------- /mcpi/connection.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import select 3 | import sys 4 | from .util import flatten_parameters_to_bytestring 5 | 6 | """ @author: Aron Nieminen, Mojang AB""" 7 | 8 | class RequestError(Exception): 9 | pass 10 | 11 | class Connection: 12 | """Connection to a Minecraft Pi game""" 13 | RequestFailed = "Fail" 14 | 15 | def __init__(self, address, port): 16 | self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 17 | self.socket.connect((address, port)) 18 | self.lastSent = "" 19 | 20 | def drain(self): 21 | """Drains the socket of incoming data""" 22 | while True: 23 | readable, _, _ = select.select([self.socket], [], [], 0.0) 24 | if not readable: 25 | break 26 | data = self.socket.recv(1500) 27 | e = "Drained Data: <%s>\n"%data.strip() 28 | e += "Last Message: <%s>\n"%self.lastSent.strip() 29 | sys.stderr.write(e) 30 | 31 | def send(self, f, *data): 32 | """Sends data. Note that a trailing newline '\n' is added here""" 33 | s = b"".join([f.encode('utf-8'), b"(", flatten_parameters_to_bytestring(data), b")", b"\n"]) 34 | self.drain() 35 | self.lastSent = s 36 | self.socket.sendall(s) 37 | 38 | def receive(self): 39 | """Receives data. Note that the trailing newline '\n' is trimmed""" 40 | s = self.socket.makefile("r").readline().rstrip("\n") 41 | if s == Connection.RequestFailed: 42 | raise RequestError("%s failed"%self.lastSent.strip()) 43 | return s 44 | 45 | def sendReceive(self, *data): 46 | """Sends and receive data""" 47 | self.send(*data) 48 | return self.receive() 49 | -------------------------------------------------------------------------------- /mcpi/event.py: -------------------------------------------------------------------------------- 1 | from .vec3 import Vec3 2 | 3 | class BlockEvent: 4 | """An Event related to blocks (e.g. placed, removed, hit)""" 5 | HIT = 0 6 | 7 | def __init__(self, type, x, y, z, face, entityId): 8 | self.type = type 9 | self.pos = Vec3(x, y, z) 10 | self.face = face 11 | self.entityId = entityId 12 | 13 | def __repr__(self): 14 | sType = { 15 | BlockEvent.HIT: "BlockEvent.HIT" 16 | }.get(self.type, "???") 17 | 18 | return "BlockEvent(%s, %d, %d, %d, %d, %d)"%( 19 | sType,self.pos.x,self.pos.y,self.pos.z,self.face,self.entityId); 20 | 21 | @staticmethod 22 | def Hit(x, y, z, face, entityId): 23 | return BlockEvent(BlockEvent.HIT, x, y, z, face, entityId) 24 | 25 | class ChatEvent: 26 | """An Event related to chat (e.g. posts)""" 27 | POST = 0 28 | 29 | def __init__(self, type, entityId, message): 30 | self.type = type 31 | self.entityId = entityId 32 | self.message = message 33 | 34 | def __repr__(self): 35 | sType = { 36 | ChatEvent.POST: "ChatEvent.POST" 37 | }.get(self.type, "???") 38 | 39 | return "ChatEvent(%s, %d, %s)"%( 40 | sType,self.entityId,self.message); 41 | 42 | @staticmethod 43 | def Post(entityId, message): 44 | return ChatEvent(ChatEvent.POST, entityId, message) 45 | -------------------------------------------------------------------------------- /mcpi/minecraft.py: -------------------------------------------------------------------------------- 1 | from .connection import Connection 2 | from .vec3 import Vec3 3 | from .event import BlockEvent, ChatEvent 4 | from .block import Block 5 | import math 6 | from .util import flatten 7 | 8 | """ Minecraft PI low level api v0.1_1 9 | 10 | Note: many methods have the parameter *arg. This solution makes it 11 | simple to allow different types, and variable number of arguments. 12 | The actual magic is a mix of flatten_parameters() and __iter__. Example: 13 | A Cube class could implement __iter__ to work in Minecraft.setBlocks(c, id). 14 | 15 | (Because of this, it's possible to "erase" arguments. CmdPlayer removes 16 | entityId, by injecting [] that flattens to nothing) 17 | 18 | @author: Aron Nieminen, Mojang AB 19 | 20 | Updated to included additional functionality provided by RaspberryJuice: 21 | - getBlocks() : implemented 22 | - .create() : can now accept "name" (player name) for use in multiplayer 23 | - CmdPositioner.getDirection 24 | - CmdPositioner.getPitch 25 | - CmdPositioner.getRotation 26 | - getPlayerEntityId 27 | - CmdEvents.pollChatPosts 28 | - CmdEvents.pollProjectileHits 29 | - CmdEvents.pollBlockHits 30 | """ 31 | 32 | 33 | def intFloor(*args): 34 | return [int(math.floor(x)) for x in flatten(args)] 35 | 36 | class CmdPositioner: 37 | """Methods for setting and getting positions""" 38 | def __init__(self, connection, packagePrefix): 39 | self.conn = connection 40 | self.pkg = packagePrefix 41 | 42 | def getPos(self, id): 43 | """Get entity position (entityId:int) => Vec3""" 44 | s = self.conn.sendReceive(self.pkg + ".getPos", id) 45 | return Vec3(*map(float, s.split(","))) 46 | 47 | def setPos(self, id, *args): 48 | """Set entity position (entityId:int, x,y,z)""" 49 | self.conn.send(self.pkg + ".setPos", id, args) 50 | 51 | def getTilePos(self, id): 52 | """Get entity tile position (entityId:int) => Vec3""" 53 | s = self.conn.sendReceive(self.pkg + ".getTile", id) 54 | return Vec3(*map(int, s.split(","))) 55 | 56 | def setTilePos(self, id, *args): 57 | """Set entity tile position (entityId:int) => Vec3""" 58 | self.conn.send(self.pkg + ".setTile", id, intFloor(*args)) 59 | 60 | def getDirection(self, id): 61 | """Get entity direction (entityId:int) => Vec3""" 62 | s = self.conn.sendReceive(self.pkg + ".getDirection", id) 63 | return Vec3(*map(float, s.split(","))) 64 | 65 | def getRotation(self, id): 66 | """get entity rotation (entityId:int) => float""" 67 | return float(self.conn.sendReceive(self.pkg + ".getRotation", id)) 68 | 69 | def getPitch(self, id): 70 | """get entity pitch (entityId:int) => float""" 71 | return float(self.conn.sendReceive(self.pkg + ".getPitch", id)) 72 | 73 | def setting(self, setting, status): 74 | """Set a player setting (setting, status). keys: autojump""" 75 | self.conn.send(self.pkg + ".setting", setting, 1 if bool(status) else 0) 76 | 77 | def pollProjectileHits(self, id): 78 | """Only triggered by projectiles => [BlockEvent]""" 79 | s = self.conn.sendReceive(self.pkg + ".events.projectile.hits", id) 80 | events = [e for e in s.split("|") if e] 81 | return [BlockEvent.Hit(*map(int, e.split(","))) for e in events] 82 | 83 | def pollChatPosts(self, id): 84 | """Triggered by posts to chat => [ChatEvent]""" 85 | s = self.conn.sendReceive(self.pkg + ".events.chat.posts", id) 86 | events = [e for e in s.split("|") if e] 87 | return [ChatEvent.Post(int(e[:e.find(",")]), e[e.find(",") + 1:]) for e in events] 88 | 89 | def pollBlockHits(self, id): 90 | """Only triggered by sword => [BlockEvent]""" 91 | s = self.conn.sendReceive(self.pkg + ".events.block.hits", id) 92 | events = [e for e in s.split("|") if e] 93 | return [BlockEvent.Hit(*map(int, e.split(","))) for e in events] 94 | 95 | 96 | class CmdEntity(CmdPositioner): 97 | """Methods for entities""" 98 | def __init__(self, connection): 99 | CmdPositioner.__init__(self, connection, "entity") 100 | 101 | 102 | class CmdPlayer(CmdPositioner): 103 | """Methods for the host (Raspberry Pi) player""" 104 | def __init__(self, connection, name=None): 105 | CmdPositioner.__init__(self, connection, "player") 106 | self.conn = connection 107 | self.name = name 108 | 109 | def getPos(self): 110 | return CmdPositioner.getPos(self, self.name) 111 | def setPos(self, *args): 112 | return CmdPositioner.setPos(self, self.name, args) 113 | def getTilePos(self): 114 | return CmdPositioner.getTilePos(self, self.name) 115 | def setTilePos(self, *args): 116 | return CmdPositioner.setTilePos(self, self.name, args) 117 | def getDirection(self): 118 | return CmdPositioner.getDirection(self, self.name) 119 | def getRotation(self): 120 | return CmdPositioner.getRotation(self, self.name) 121 | def getPitch(self): 122 | return CmdPositioner.getPitch(self, self.name) 123 | def pollProjectileHits(self): 124 | return CmdPositioner.pollProjectileHits(self, self.name) 125 | def pollChatPosts(self): 126 | return CmdPositioner.pollChatPosts(self, self.name) 127 | def pollBlockHits(self): 128 | return CmdPositioner.pollBlockHits(self, self.name) 129 | 130 | class CmdCamera: 131 | def __init__(self, connection): 132 | self.conn = connection 133 | 134 | def setNormal(self, *args): 135 | """Set camera mode to normal Minecraft view ([entityId])""" 136 | self.conn.send("camera.mode.setNormal", args) 137 | 138 | def setFixed(self): 139 | """Set camera mode to fixed view""" 140 | self.conn.send("camera.mode.setFixed") 141 | 142 | def setFollow(self, *args): 143 | """Set camera mode to follow an entity ([entityId])""" 144 | self.conn.send("camera.mode.setFollow", args) 145 | 146 | def setPos(self, *args): 147 | """Set camera entity position (x,y,z)""" 148 | self.conn.send("camera.setPos", args) 149 | 150 | 151 | class CmdEvents: 152 | """Events""" 153 | def __init__(self, connection): 154 | self.conn = connection 155 | 156 | def clearAll(self): 157 | """Clear all old events""" 158 | self.conn.send("events.clear") 159 | 160 | class Minecraft: 161 | """The main class to interact with a running instance of Minecraft Pi.""" 162 | def __init__(self, connection, name=None): 163 | self.conn = connection 164 | 165 | self.camera = CmdCamera(connection) 166 | self.entity = CmdEntity(connection) 167 | self.player = CmdPlayer(connection, name) 168 | self.events = CmdEvents(connection) 169 | 170 | def getBlock(self, *args): 171 | """Get block (x,y,z) => id:int""" 172 | return int(self.conn.sendReceive("world.getBlock", intFloor(args))) 173 | 174 | def getBlockWithData(self, *args): 175 | """Get block with data (x,y,z) => Block""" 176 | ans = self.conn.sendReceive("world.getBlockWithData", intFloor(args)) 177 | return Block(*map(int, ans.split(","))) 178 | """ 179 | @TODO 180 | """ 181 | def getBlocks(self, *args): 182 | """Get a cuboid of blocks (x0,y0,z0,x1,y1,z1) => [id:int]""" 183 | s = self.conn.sendReceive("world.getBlocks", intFloor(args)) 184 | return map(int, s.split(",")) 185 | 186 | def setBlock(self, *args): 187 | """Set block (x,y,z,id,[data])""" 188 | self.conn.send("world.setBlock", intFloor(args)) 189 | 190 | def setBlocks(self, *args): 191 | """Set a cuboid of blocks (x0,y0,z0,x1,y1,z1,id,[data])""" 192 | self.conn.send("world.setBlocks", intFloor(args)) 193 | 194 | def getHeight(self, *args): 195 | """Get the height of the world (x,z) => int""" 196 | return int(self.conn.sendReceive("world.getHeight", intFloor(args))) 197 | 198 | def getPlayerEntityIds(self): 199 | """Get the entity ids of the connected players => [id:int]""" 200 | ids = self.conn.sendReceive("world.getPlayerIds") 201 | return map(int, ids.split("|")) 202 | 203 | def getPlayerEntityId(self, name): 204 | """Get the entity id of the named player => [id:int]""" 205 | return int(self.conn.sendReceive("world.getPlayerId", name)) 206 | 207 | def saveCheckpoint(self): 208 | """Save a checkpoint that can be used for restoring the world""" 209 | self.conn.send("world.checkpoint.save") 210 | 211 | def restoreCheckpoint(self): 212 | """Restore the world state to the checkpoint""" 213 | self.conn.send("world.checkpoint.restore") 214 | 215 | def postToChat(self, msg): 216 | """Post a message to the game chat""" 217 | self.conn.send("chat.post", msg) 218 | 219 | def setting(self, setting, status): 220 | """Set a world setting (setting, status). keys: world_immutable, nametags_visible""" 221 | self.conn.send("world.setting", setting, 1 if bool(status) else 0) 222 | 223 | @staticmethod 224 | def create(address = "localhost", port = 4711, name = None): 225 | return Minecraft(Connection(address, port), name) 226 | 227 | 228 | if __name__ == "__main__": 229 | mc = Minecraft.create() 230 | mc.postToChat("Hello, Minecraft!") 231 | -------------------------------------------------------------------------------- /mcpi/util.py: -------------------------------------------------------------------------------- 1 | import collections 2 | 3 | def flatten(l): 4 | for e in l: 5 | if isinstance(e, collections.Iterable) and not isinstance(e, str): 6 | for ee in flatten(e): yield ee 7 | else: yield e 8 | 9 | def flatten_parameters_to_bytestring(l): 10 | return b",".join(map(_misc_to_bytes, flatten(l))) 11 | 12 | def _misc_to_bytes(m): 13 | return str(m).encode("cp437") -------------------------------------------------------------------------------- /mcpi/vec3.py: -------------------------------------------------------------------------------- 1 | class Vec3: 2 | def __init__(self, x=0, y=0, z=0): 3 | self.x = x 4 | self.y = y 5 | self.z = z 6 | 7 | def __add__(self, rhs): 8 | c = self.clone() 9 | c += rhs 10 | return c 11 | 12 | def __iadd__(self, rhs): 13 | self.x += rhs.x 14 | self.y += rhs.y 15 | self.z += rhs.z 16 | return self 17 | 18 | def length(self): 19 | return self.lengthSqr ** .5 20 | 21 | def lengthSqr(self): 22 | return self.x * self.x + self.y * self.y + self.z * self.z 23 | 24 | def __mul__(self, k): 25 | c = self.clone() 26 | c *= k 27 | return c 28 | 29 | def __imul__(self, k): 30 | self.x *= k 31 | self.y *= k 32 | self.z *= k 33 | return self 34 | 35 | def clone(self): 36 | return Vec3(self.x, self.y, self.z) 37 | 38 | def __neg__(self): 39 | return Vec3(-self.x, -self.y, -self.z) 40 | 41 | def __sub__(self, rhs): 42 | return self.__add__(-rhs) 43 | 44 | def __isub__(self, rhs): 45 | return self.__iadd__(-rhs) 46 | 47 | def __repr__(self): 48 | return "Vec3(%s,%s,%s)"%(self.x,self.y,self.z) 49 | 50 | def __iter__(self): 51 | return iter((self.x, self.y, self.z)) 52 | 53 | def _map(self, func): 54 | self.x = func(self.x) 55 | self.y = func(self.y) 56 | self.z = func(self.z) 57 | 58 | def __cmp__(self, rhs): 59 | dx = self.x - rhs.x 60 | if dx != 0: return dx 61 | dy = self.y - rhs.y 62 | if dy != 0: return dy 63 | dz = self.z - rhs.z 64 | if dz != 0: return dz 65 | return 0 66 | 67 | def iround(self): self._map(lambda v:int(v+0.5)) 68 | def ifloor(self): self._map(int) 69 | 70 | def rotateLeft(self): self.x, self.z = self.z, -self.x 71 | def rotateRight(self): self.x, self.z = -self.z, self.x 72 | 73 | def testVec3(): 74 | # Note: It's not testing everything 75 | 76 | # 1.1 Test initialization 77 | it = Vec3(1, -2, 3) 78 | assert it.x == 1 79 | assert it.y == -2 80 | assert it.z == 3 81 | 82 | assert it.x != -1 83 | assert it.y != +2 84 | assert it.z != -3 85 | 86 | # 2.1 Test cloning and equality 87 | clone = it.clone() 88 | assert it == clone 89 | it.x += 1 90 | assert it != clone 91 | 92 | # 3.1 Arithmetic 93 | a = Vec3(10, -3, 4) 94 | b = Vec3(-7, 1, 2) 95 | c = a + b 96 | assert c - a == b 97 | assert c - b == a 98 | assert a + a == a * 2 99 | 100 | assert a - a == Vec3(0,0,0) 101 | assert a + (-a) == Vec3(0,0,0) 102 | 103 | # Test repr 104 | e = eval(repr(it)) 105 | assert e == it 106 | 107 | if __name__ == "__main__": 108 | testVec3() 109 | -------------------------------------------------------------------------------- /minecraftstuff/__init__.py: -------------------------------------------------------------------------------- 1 | from .minecraftstuff import MinecraftDrawing, MinecraftShape, MinecraftTurtle, ShapeBlock, Points 2 | -------------------------------------------------------------------------------- /minecraftstuff/minecraftstuff.py: -------------------------------------------------------------------------------- 1 | #www.stuffaboutcode.com 2 | #github.com/martinohanlon/minecraft-stuff 3 | #Raspberry Pi, Minecraft - Minecraft 'stuff' extensions 4 | 5 | try: 6 | import mcpi.minecraft as minecraft 7 | import mcpi.block as block 8 | import mcpi.util as util 9 | except ImportError: 10 | import minecraft 11 | import block 12 | import util 13 | 14 | from copy import deepcopy 15 | import time 16 | import math 17 | 18 | class Points(): 19 | """ 20 | Points - a collection of minecraft positions or Vec3's. Used when drawing faces ``MinecraftDrawing.drawFace()``. 21 | """ 22 | def __init__(self): 23 | self._points = [] 24 | 25 | def add(self, x, y, z): 26 | """ 27 | add a single position to the list of points. 28 | 29 | :param int x: 30 | The x position. 31 | 32 | :param int y: 33 | The y position. 34 | 35 | :param int z: 36 | The z position. 37 | """ 38 | self._points.append(minecraft.Vec3(x, y, z)) 39 | 40 | def getVec3s(self): 41 | """ 42 | returns a list of Vec3 positions 43 | """ 44 | return self._points 45 | 46 | class MinecraftDrawing: 47 | """ 48 | MinecraftDrawing - a class of useful drawing functions 49 | 50 | :param mcpi.minecraft.Minecraft mc: 51 | A Minecraft object which is connected to a world. 52 | """ 53 | def __init__(self, mc): 54 | self.mc = mc 55 | 56 | def drawPoint3d(self, x, y, z, blockType, blockData=0): 57 | """ 58 | draws a single point in Minecraft, i.e. 1 block 59 | 60 | :param int x: 61 | The x position. 62 | 63 | :param int y: 64 | The y position. 65 | 66 | :param int z: 67 | The z position. 68 | 69 | :param int blockType: 70 | The block id. 71 | 72 | :param int blockData: 73 | The block data value, defaults to ``0``. 74 | """ 75 | 76 | self.mc.setBlock(x,y,z,blockType,blockData) 77 | #print "x = " + str(x) + ", y = " + str(y) + ", z = " + str(z) 78 | 79 | def drawFace(self, vertices, filled, blockType, blockData=0): 80 | """ 81 | draws a face, when passed a collection of vertices which make up a polyhedron 82 | 83 | :param list vertices: 84 | The a list of points, passed as either a ``minecraftstuff.Points`` object 85 | or as a list of ``mcpi.minecraft.Vec3`` objects. 86 | 87 | :param boolean filled: 88 | If ``True`` fills the face with blocks. 89 | 90 | :param int blockType: 91 | The block id. 92 | 93 | :param int blockData: 94 | The block data value, defaults to ``0``. 95 | """ 96 | 97 | # was a Points class passed? If so get the list of Vec3s. 98 | if isinstance(vertices, Points): 99 | vertices = vertices.getVec3s() 100 | 101 | # get the edges of the face 102 | edgesVertices = [] 103 | # persist the first vertex 104 | firstVertex = vertices[0] 105 | # get the last vertex 106 | lastVertex = vertices[0] 107 | 108 | # loop through vertices and get edges 109 | for vertex in vertices[1:]: 110 | # get the points for the edge 111 | edgesVertices = edgesVertices + self.getLine(lastVertex.x, lastVertex.y, lastVertex.z, vertex.x, vertex.y, vertex.z) 112 | # persist the last vertex found 113 | lastVertex = vertex 114 | 115 | # get edge between the last and first vertices, so the polyhedron 'joins up' 116 | edgesVertices = edgesVertices + self.getLine(lastVertex.x, lastVertex.y, lastVertex.z, firstVertex.x, firstVertex.y, firstVertex.z) 117 | 118 | if (filled): 119 | #draw solid face 120 | # this algorithm isnt very efficient, but it does always fill the gap 121 | 122 | # sort the edges vertices 123 | def keyX( point ): return point.x 124 | def keyY( point ): return point.y 125 | def keyZ( point ): return point.z 126 | edgesVertices.sort( key=keyZ ) 127 | edgesVertices.sort( key=keyY ) 128 | edgesVertices.sort( key=keyX ) 129 | 130 | #draw lines between the points on the edges 131 | lastVertex = edgesVertices[0] 132 | for vertex in edgesVertices[1:]: 133 | # got 2 vertices, draw lines between them 134 | self.drawLine(lastVertex.x, lastVertex.y, lastVertex.z, vertex.x, vertex.y, vertex.z, blockType, blockData) 135 | #print "x = " + str(lastVertex.x) + ", y = " + str(lastVertex.y) + ", z = " + str(lastVertex.z) + " x2 = " + str(vertex.x) + ", y2 = " + str(vertex.y) + ", z2 = " + str(vertex.z) 136 | # persist the last vertex found 137 | lastVertex = vertex 138 | 139 | else: 140 | #draw wireframe 141 | self.drawVertices(edgesVertices, blockType, blockData) 142 | 143 | def drawVertices(self, vertices, blockType, blockData=0): 144 | """ 145 | draws all the points in a collection of vertices with a block 146 | 147 | :param list vertices: 148 | A list of ``mcpi.minecraft.Vec3`` objects. 149 | 150 | :param int blockType: 151 | The block id. 152 | 153 | :param int blockData: 154 | The block data value, defaults to ``0``. 155 | """ 156 | 157 | for vertex in vertices: 158 | self.drawPoint3d(vertex.x, vertex.y, vertex.z, blockType, blockData) 159 | 160 | def drawLine(self, x1, y1, z1, x2, y2, z2, blockType, blockData=0): 161 | """ 162 | draws a line between 2 points 163 | 164 | :param int x1: 165 | The x position of the first point. 166 | 167 | :param int y1: 168 | The y position of the first point. 169 | 170 | :param int z1: 171 | The z position of the first point. 172 | 173 | :param int x2: 174 | The x position of the second point. 175 | 176 | :param int y2: 177 | The y position of the second point. 178 | 179 | :param int z2: 180 | The z position of the second point. 181 | 182 | :param int blockType: 183 | The block id. 184 | 185 | :param int blockData: 186 | The block data value, defaults to ``0``. 187 | """ 188 | self.drawVertices(self.getLine(x1, y1, z1, x2, y2, z2), blockType, blockData) 189 | 190 | 191 | def drawSphere(self, x1, y1, z1, radius, blockType, blockData=0): 192 | """ 193 | draws a sphere around a point to a radius 194 | 195 | :param int x1: 196 | The x position of the centre of the sphere. 197 | 198 | :param int y1: 199 | The y position of the centre of the sphere. 200 | 201 | :param int z1: 202 | The z position of the centre of the sphere. 203 | 204 | :param int radius: 205 | The radius of the sphere. 206 | 207 | :param int blockType: 208 | The block id. 209 | 210 | :param int blockData: 211 | The block data value, defaults to ``0``. 212 | """ 213 | for x in range(radius * -1, radius): 214 | for y in range(radius * -1, radius): 215 | for z in range(radius * -1, radius): 216 | if x**2 + y**2 + z**2 < radius**2: 217 | self.drawPoint3d(x1 + x, y1 + y, z1 + z, blockType, blockData) 218 | 219 | def drawHollowSphere(self, x1, y1, z1, radius, blockType, blockData=0): 220 | """ 221 | draws a hollow sphere around a point to a radius, sphere has to big enough to be hollow! 222 | 223 | :param int x1: 224 | The x position of the centre of the sphere. 225 | 226 | :param int y1: 227 | The y position of the centre of the sphere. 228 | 229 | :param int z1: 230 | The z position of the centre of the sphere. 231 | 232 | :param int radius: 233 | The radius of the sphere. 234 | 235 | :param int blockType: 236 | The block id. 237 | 238 | :param int blockData: 239 | The block data value, defaults to ``0``. 240 | """ 241 | for x in range(radius * -1, radius): 242 | for y in range(radius * -1, radius): 243 | for z in range(radius * -1, radius): 244 | if (x**2 + y**2 + z**2 < radius**2) and (x**2 + y**2 + z**2 > (radius**2 - (radius * 2))): 245 | self.drawPoint3d(x1 + x, y1 + y, z1 +z, blockType, blockData) 246 | 247 | def drawCircle(self, x0, y0, z, radius, blockType, blockData=0): 248 | """ 249 | draws a circle in the Y plane (i.e. vertically) 250 | 251 | :param int x0: 252 | The x position of the centre of the circle. 253 | 254 | :param int y0: 255 | The y position of the centre of the circle. 256 | 257 | :param int z: 258 | The z position of the centre of the circle. 259 | 260 | :param int radius: 261 | The radius of the sphere. 262 | 263 | :param int blockType: 264 | The block id. 265 | 266 | :param int blockData: 267 | The block data value, defaults to ``0``. 268 | """ 269 | 270 | f = 1 - radius 271 | ddf_x = 1 272 | ddf_y = -2 * radius 273 | x = 0 274 | y = radius 275 | self.drawPoint3d(x0, y0 + radius, z, blockType, blockData) 276 | self.drawPoint3d(x0, y0 - radius, z, blockType, blockData) 277 | self.drawPoint3d(x0 + radius, y0, z, blockType, blockData) 278 | self.drawPoint3d(x0 - radius, y0, z, blockType, blockData) 279 | 280 | while x < y: 281 | if f >= 0: 282 | y -= 1 283 | ddf_y += 2 284 | f += ddf_y 285 | x += 1 286 | ddf_x += 2 287 | f += ddf_x 288 | self.drawPoint3d(x0 + x, y0 + y, z, blockType, blockData) 289 | self.drawPoint3d(x0 - x, y0 + y, z, blockType, blockData) 290 | self.drawPoint3d(x0 + x, y0 - y, z, blockType, blockData) 291 | self.drawPoint3d(x0 - x, y0 - y, z, blockType, blockData) 292 | self.drawPoint3d(x0 + y, y0 + x, z, blockType, blockData) 293 | self.drawPoint3d(x0 - y, y0 + x, z, blockType, blockData) 294 | self.drawPoint3d(x0 + y, y0 - x, z, blockType, blockData) 295 | self.drawPoint3d(x0 - y, y0 - x, z, blockType, blockData) 296 | 297 | 298 | def drawHorizontalCircle(self, x0, y, z0, radius, blockType, blockData=0): 299 | """ 300 | draws a circle in the X plane (i.e. horizontally) 301 | 302 | :param int x0: 303 | The x position of the centre of the circle. 304 | 305 | :param int y: 306 | The y position of the centre of the circle. 307 | 308 | :param int z0: 309 | The z position of the centre of the circle. 310 | 311 | :param int radius: 312 | The radius of the circle. 313 | 314 | :param int blockType: 315 | The block id. 316 | 317 | :param int blockData: 318 | The block data value, defaults to ``0``. 319 | """ 320 | 321 | f = 1 - radius 322 | ddf_x = 1 323 | ddf_z = -2 * radius 324 | x = 0 325 | z = radius 326 | self.drawPoint3d(x0, y, z0 + radius, blockType, blockData) 327 | self.drawPoint3d(x0, y, z0 - radius, blockType, blockData) 328 | self.drawPoint3d(x0 + radius, y, z0, blockType, blockData) 329 | self.drawPoint3d(x0 - radius, y, z0, blockType, blockData) 330 | 331 | while x < z: 332 | if f >= 0: 333 | z -= 1 334 | ddf_z += 2 335 | f += ddf_z 336 | x += 1 337 | ddf_x += 2 338 | f += ddf_x 339 | self.drawPoint3d(x0 + x, y, z0 + z, blockType, blockData) 340 | self.drawPoint3d(x0 - x, y, z0 + z, blockType, blockData) 341 | self.drawPoint3d(x0 + x, y, z0 - z, blockType, blockData) 342 | self.drawPoint3d(x0 - x, y, z0 - z, blockType, blockData) 343 | self.drawPoint3d(x0 + z, y, z0 + x, blockType, blockData) 344 | self.drawPoint3d(x0 - z, y, z0 + x, blockType, blockData) 345 | self.drawPoint3d(x0 + z, y, z0 - x, blockType, blockData) 346 | self.drawPoint3d(x0 - z, y, z0 - x, blockType, blockData) 347 | 348 | def getLine(self, x1, y1, z1, x2, y2, z2): 349 | """ 350 | Returns all the points which would make up a line between 2 points as a list 351 | 352 | 3d implementation of bresenham line algorithm 353 | 354 | :param int x1: 355 | The x position of the first point. 356 | 357 | :param int y1: 358 | The y position of the first point. 359 | 360 | :param int z1: 361 | The z position of the first point. 362 | 363 | :param int x2: 364 | The x position of the second point. 365 | 366 | :param int y2: 367 | The y position of the second point. 368 | 369 | :param int z2: 370 | The z position of the second point. 371 | """ 372 | # return the maximum of 2 values 373 | def MAX(a,b): 374 | if a > b: return a 375 | else: return b 376 | 377 | # return step 378 | def ZSGN(a): 379 | if a < 0: return -1 380 | elif a > 0: return 1 381 | elif a == 0: return 0 382 | 383 | # list for vertices 384 | vertices = [] 385 | 386 | # if the 2 points are the same, return single vertice 387 | if (x1 == x2 and y1 == y2 and z1 == z2): 388 | vertices.append(minecraft.Vec3(x1, y1, z1)) 389 | 390 | # else get all points in edge 391 | else: 392 | 393 | dx = x2 - x1 394 | dy = y2 - y1 395 | dz = z2 - z1 396 | 397 | ax = abs(dx) << 1 398 | ay = abs(dy) << 1 399 | az = abs(dz) << 1 400 | 401 | sx = ZSGN(dx) 402 | sy = ZSGN(dy) 403 | sz = ZSGN(dz) 404 | 405 | x = x1 406 | y = y1 407 | z = z1 408 | 409 | # x dominant 410 | if (ax >= MAX(ay, az)): 411 | yd = ay - (ax >> 1) 412 | zd = az - (ax >> 1) 413 | loop = True 414 | while(loop): 415 | vertices.append(minecraft.Vec3(x, y, z)) 416 | if (x == x2): 417 | loop = False 418 | if (yd >= 0): 419 | y += sy 420 | yd -= ax 421 | if (zd >= 0): 422 | z += sz 423 | zd -= ax 424 | x += sx 425 | yd += ay 426 | zd += az 427 | # y dominant 428 | elif (ay >= MAX(ax, az)): 429 | xd = ax - (ay >> 1) 430 | zd = az - (ay >> 1) 431 | loop = True 432 | while(loop): 433 | vertices.append(minecraft.Vec3(x, y, z)) 434 | if (y == y2): 435 | loop=False 436 | if (xd >= 0): 437 | x += sx 438 | xd -= ay 439 | if (zd >= 0): 440 | z += sz 441 | zd -= ay 442 | y += sy 443 | xd += ax 444 | zd += az 445 | # z dominant 446 | elif(az >= MAX(ax, ay)): 447 | xd = ax - (az >> 1) 448 | yd = ay - (az >> 1) 449 | loop = True 450 | while(loop): 451 | vertices.append(minecraft.Vec3(x, y, z)) 452 | if (z == z2): 453 | loop=False 454 | if (xd >= 0): 455 | x += sx 456 | xd -= az 457 | if (yd >= 0): 458 | y += sy 459 | yd -= az 460 | z += sz 461 | xd += ax 462 | yd += ay 463 | 464 | return vertices 465 | 466 | # MinecraftShape - a class for managing shapes 467 | class MinecraftShape: 468 | """ 469 | MinecraftShape - the implementation of a 'shape' in Minecraft. 470 | 471 | Each shape consists of one or many blocks with a position relative to each other. 472 | 473 | Shapes can be transformed by movement and rotation. 474 | 475 | When a shape is changed and redrawn in Minecraft only the blocks which have changed are updated. 476 | 477 | :param mcpi.minecraft.Minecraft mc: 478 | A Minecraft object which is connected to a world. 479 | 480 | :param mcpi.minecraft.Vec3 position: 481 | The position where the shape should be created 482 | 483 | :param list shapeBlocks: 484 | A list of ShapeBlocks which make up the shape. This defaults to ``None``. 485 | 486 | :param bool visible: 487 | Where the shape should be visible. This defaults to ``True``. 488 | """ 489 | 490 | def __init__(self, mc, position, shapeBlocks = None, visible = True): 491 | #persist the data 492 | self.mc = mc 493 | self.position = position 494 | self.originalPos = self.position.clone() 495 | 496 | if shapeBlocks == None: 497 | self.shapeBlocks = [] 498 | else: 499 | self.shapeBlocks = shapeBlocks 500 | 501 | self.visible = visible 502 | 503 | #setup properties 504 | 505 | #drawnShapeBlocks is the last positions the shape was drawn too 506 | self.drawnShapeBlocks = None 507 | 508 | #set yaw, pitch, roll 509 | self.yaw, self.pitch, self.roll = 0, 0, 0 510 | 511 | #move the shape to its starting position 512 | self._move(position.x, position.y, position.z) 513 | 514 | def draw(self): 515 | """ 516 | draws the shape in Minecraft, taking into account where it was last drawn, 517 | only updating the blocks which have changed 518 | """ 519 | 520 | #create 2 sets only of the blocks which are drawn and one of the shapeBlocks 521 | if self.drawnShapeBlocks == None: 522 | drawnSet = set() 523 | else: 524 | drawnSet = set(self.drawnShapeBlocks) 525 | currentSet = set(self.shapeBlocks) 526 | 527 | #work out the blocks which need to be cleared 528 | for blockToClear in drawnSet - currentSet: 529 | self.mc.setBlock(blockToClear.actualPos.x, blockToClear.actualPos.y, blockToClear.actualPos.z, block.AIR.id) 530 | 531 | #work out the blocks which have changed and need to be re-drawn 532 | for blockToDraw in currentSet - drawnSet: 533 | self.mc.setBlock(blockToDraw.actualPos.x, blockToDraw.actualPos.y, blockToDraw.actualPos.z, blockToDraw.blockType, blockToDraw.blockData) 534 | 535 | #update the blocks which have been drawn 536 | self.drawnShapeBlocks = deepcopy(self.shapeBlocks) 537 | self.visible = True 538 | 539 | def redraw(self): 540 | """ 541 | redraws the shape in Minecraft, by clearing all the blocks and redrawing them 542 | """ 543 | if self.drawnShapeBlocks != None: 544 | for blockToClear in self.drawnShapeBlocks: 545 | self.mc.setBlock(blockToClear.actualPos.x, blockToClear.actualPos.y, blockToClear.actualPos.z, block.AIR.id) 546 | 547 | for blockToDraw in self.shapeBlocks: 548 | self.mc.setBlock(blockToDraw.actualPos.x, blockToDraw.actualPos.y, blockToDraw.actualPos.z, blockToDraw.blockType, blockToDraw.blockData) 549 | 550 | #update the blocks which have been drawn 551 | self.drawnShapeBlocks = deepcopy(self.shapeBlocks) 552 | self.visible = True 553 | 554 | def clear(self): 555 | """ 556 | clears the shape in Minecraft 557 | """ 558 | #clear the shape 559 | if self.drawnShapeBlocks != None: 560 | for blockToClear in self.drawnShapeBlocks: 561 | self.mc.setBlock(blockToClear.actualPos.x, 562 | blockToClear.actualPos.y, 563 | blockToClear.actualPos.z, 564 | block.AIR.id) 565 | self.drawnShapeBlocks = None 566 | 567 | self.visible = False 568 | 569 | def reset(self): 570 | """ 571 | resets the shape back to its original position 572 | """ 573 | self.rotate(0,0,0) 574 | self.move(self.originalPos.x, self.originalPos.y, self.originalPos.z) 575 | 576 | def moveBy(self, x, y, z): 577 | """ 578 | moves the position of the shape by x,y,z 579 | 580 | :param int x: 581 | The number of blocks to move in x. 582 | 583 | :param int y: 584 | The number of blocks to move in y. 585 | 586 | :param int z: 587 | The number of blocks to move in z. 588 | 589 | """ 590 | return self._move(self.position.x + x, self.position.y + y, self.position.z + z) 591 | 592 | def move(self, x, y, z): 593 | """ 594 | moves the position of the shape to x,y,z 595 | 596 | :param int x: 597 | The x position. 598 | 599 | :param int y: 600 | The y position. 601 | 602 | :param int z: 603 | The z position. 604 | """ 605 | #is the position different 606 | if self.position.x != x or self.position.y != y or self.position.z != z: 607 | self.position.x = x 608 | self.position.y = y 609 | self.position.z = z 610 | 611 | self._recalcBlocks() 612 | 613 | if self.visible: 614 | self.draw() 615 | 616 | return True 617 | 618 | else: 619 | 620 | return False 621 | 622 | def _move(self, x, y, z): 623 | """ 624 | Internal. moves the position of the shape to x,y,z 625 | """ 626 | self.position.x = x 627 | self.position.y = y 628 | self.position.z = z 629 | 630 | self._recalcBlocks() 631 | 632 | if self.visible: 633 | self.draw() 634 | 635 | def _recalcBlocks(self): 636 | """ 637 | Internal. recalculate the position of all of the blocks in a shape 638 | """ 639 | for shapeBlock in self.shapeBlocks: 640 | self._recalcBlock(shapeBlock) 641 | 642 | def _recalcBlock(self, shapeBlock): 643 | """ 644 | Internal. recalulate the shapeBlock's position based on its relative position, 645 | its actual position in the world and its rotation 646 | """ 647 | #reset the block's position before recalcing it 648 | shapeBlock.resetRelativePos() 649 | 650 | #rotate the block 651 | self._rotateShapeBlock(shapeBlock, self.yaw, self.pitch, self.roll) 652 | 653 | #move the block 654 | self._moveShapeBlock(shapeBlock, self.position.x, self.position.y, self.position.z) 655 | 656 | def rotate(self, yaw, pitch, roll): 657 | """ 658 | sets the rotation of a shape by yaw, pitch and roll 659 | 660 | :param float yaw: 661 | The yaw rotation in degrees. 662 | 663 | :param float pitch: 664 | The pitch rotation in degrees. 665 | 666 | :param float roll: 667 | The roll rotation in degrees. 668 | """ 669 | #is the rotation different? 670 | if yaw != self.yaw or pitch != self.pitch or roll != self.roll: 671 | 672 | #update values 673 | self.yaw, self.pitch, self.roll = yaw, pitch, roll 674 | 675 | #recalc all the block positions 676 | self._recalcBlocks() 677 | 678 | #if its visible redraw it 679 | if self.visible: 680 | self.draw() 681 | 682 | return True 683 | 684 | else: 685 | 686 | return False 687 | 688 | def rotateBy(self, yaw, pitch, roll): 689 | """ 690 | increments the rotation of a shape by yaw, pitch and roll 691 | 692 | :param float yaw: 693 | The yaw rotation in degrees. 694 | 695 | :param float pitch: 696 | The pitch rotation in degrees. 697 | 698 | :param float roll: 699 | The roll rotation in degrees. 700 | """ 701 | return self.rotate(self.yaw + yaw, self.pitch + pitch, self.roll + roll) 702 | 703 | def _moveShapeBlock(self, shapeBlock, x, y, z): 704 | """ 705 | Internal. offset the position of the block by the position 706 | """ 707 | shapeBlock.actualPos.x = shapeBlock.relativePos.x + x 708 | shapeBlock.actualPos.y = shapeBlock.relativePos.y + y 709 | shapeBlock.actualPos.z = shapeBlock.relativePos.z + z 710 | 711 | def _rotateShapeBlock(self, shapeBlock, yaw, pitch, roll): 712 | """ 713 | Internal. rotate the block 714 | """ 715 | self._rotateShapeBlockY(shapeBlock, yaw) 716 | self._rotateShapeBlockZ(shapeBlock, roll) 717 | self._rotateShapeBlockX(shapeBlock, pitch) 718 | 719 | 720 | def _rotateShapeBlockY(self, shapeBlock, theta): 721 | """ 722 | Internal. rotate y = yaw (direction) 723 | """ 724 | if theta != 0: 725 | sin_t = math.sin(math.radians(theta)) 726 | cos_t = math.cos(math.radians(theta)) 727 | x = shapeBlock.relativePos.x * cos_t - shapeBlock.relativePos.z * sin_t 728 | z = shapeBlock.relativePos.z * cos_t + shapeBlock.relativePos.x * sin_t 729 | shapeBlock.relativePos.x = int(round(x,0)) 730 | shapeBlock.relativePos.z = int(round(z,0)) 731 | 732 | def _rotateShapeBlockZ(self, shapeBlock, theta): 733 | """ 734 | Internal. rotate z = roll 735 | """ 736 | if theta != 0: 737 | sin_t = math.sin(math.radians(theta)) 738 | cos_t = math.cos(math.radians(theta)) 739 | x = shapeBlock.relativePos.x * cos_t - shapeBlock.relativePos.y * sin_t 740 | y = shapeBlock.relativePos.y * cos_t + shapeBlock.relativePos.x * sin_t 741 | shapeBlock.relativePos.x = int(round(x,0)) 742 | shapeBlock.relativePos.y = int(round(y,0)) 743 | 744 | def _rotateShapeBlockX(self, shapeBlock, theta): 745 | """ 746 | Internal. rotate x = pitch 747 | """ 748 | if theta != 0: 749 | sin_t = math.sin(math.radians(theta)) 750 | cos_t = math.cos(math.radians(theta)) 751 | y = shapeBlock.relativePos.y * cos_t - shapeBlock.relativePos.z * sin_t 752 | z = shapeBlock.relativePos.z * cos_t + shapeBlock.relativePos.y * sin_t 753 | shapeBlock.relativePos.y = int(round(y,0)) 754 | shapeBlock.relativePos.z = int(round(z,0)) 755 | 756 | def setBlock(self, x, y, z, blockType, blockData = 0, tag = ""): 757 | """ 758 | sets one block in the shape and redraws it 759 | 760 | draws a single point in Minecraft, i.e. 1 block 761 | 762 | :param int x: 763 | The x position. 764 | 765 | :param int y: 766 | The y position. 767 | 768 | :param int z: 769 | The z position. 770 | 771 | :param int blockType: 772 | The block id. 773 | 774 | :param int blockData: 775 | The block data value, defaults to ``0``. 776 | 777 | :param string tag: 778 | A tag for the block, this is useful for grouping blocks together and keeping 779 | track of them as the position of blocks can change, defaults to ``""``. 780 | """ 781 | self._setBlock(x, y, z, blockType, blockData, tag) 782 | 783 | #if the shape is visible (re)draw it 784 | if self.visible: 785 | self.draw() 786 | 787 | def _setBlock(self, x, y, z, blockType, blockData, tag): 788 | """ 789 | sets one block in the shape 790 | """ 791 | #does the block already exist? 792 | for shapeBlock in self.shapeBlocks: 793 | if shapeBlock.originalPos.x == x and shapeBlock.originalPos.y == y and shapeBlock.originalPos.z == z: 794 | #it does exist, update it 795 | shapeBlock.blockType = blockType 796 | shapeBlock.blockData = blockData 797 | shapeBlock.tag= tag 798 | break 799 | else: 800 | #it doesn't append it 801 | newShapeBlock = ShapeBlock(x, y, z, blockType, blockData, tag) 802 | self._recalcBlock(newShapeBlock) 803 | self.shapeBlocks.append(newShapeBlock) 804 | 805 | def setBlocks(self, x1, y1, z1, x2, y2, z2, blockType, blockData = 0, tag = ""): 806 | """ 807 | creates a cuboid of blocks in the shape and redraws it 808 | 809 | :param int x1: 810 | The x position of the first point. 811 | 812 | :param int y1: 813 | The y position of the first point. 814 | 815 | :param int z1: 816 | The z position of the first point. 817 | 818 | :param int x2: 819 | The x position of the second point. 820 | 821 | :param int y2: 822 | The y position of the second point. 823 | 824 | :param int z2: 825 | The z position of the second point. 826 | 827 | :param int blockType: 828 | The block id. 829 | 830 | :param int blockData: 831 | The block data value, defaults to ``0``. 832 | 833 | :param string tag: 834 | A tag for the block, this is useful for grouping blocks together and keeping 835 | track of them as the position of blocks can change, defaults to ``""``. 836 | """ 837 | #order x, y, z's 838 | if x1 > x2: x1, x2 = x2, x1 839 | if y1 > y2: y1, y2 = y2, y1 840 | if z1 > z2: z1, z2 = z2, z1 841 | 842 | #create the cuboid 843 | for x in range(x1, x2 + 1): 844 | for y in range(y1, y2 + 1): 845 | for z in range(z1, z2 + 1): 846 | self._setBlock(x, y, z, blockType, blockData, tag) 847 | 848 | #if the shape is visible (re)draw it 849 | if self.visible: 850 | self.draw() 851 | 852 | def getShapeBlock(self, x, y, z): 853 | """ 854 | returns the ShapeBlock for an 'actual position' 855 | 856 | :param int x: 857 | The x position. 858 | 859 | :param int y: 860 | The y position. 861 | 862 | :param int z: 863 | The z position. 864 | """ 865 | #does the block exist? 866 | for shapeBlock in self.shapeBlocks: 867 | if shapeBlock.actualPos.x == x and shapeBlock.actualPos.y == y and shapeBlock.actualPos.z == z: 868 | return shapeBlock 869 | else: 870 | #it doesn't return None 871 | return None 872 | 873 | # a class created to manage a block within a shape 874 | class ShapeBlock(): 875 | """ 876 | ShapeBlock - a class to hold one block within a shape 877 | 878 | :param int x: 879 | The x position. 880 | 881 | :param int y: 882 | The y position. 883 | 884 | :param int z: 885 | The z position. 886 | 887 | :param int blockType: 888 | The block id. 889 | 890 | :param int blockData: 891 | The block data value, defaults to ``0``. 892 | 893 | :param string tag: 894 | A tag for the block, this is useful for grouping blocks together and keeping 895 | track of them as the position of blocks can change, defaults to ``""``. 896 | """ 897 | def __init__(self, x, y, z, blockType, blockData = 0, tag = ""): 898 | #persist data 899 | self.blockType = blockType 900 | self.blockData = blockData 901 | 902 | #store the positions 903 | # original pos 904 | self.originalPos = minecraft.Vec3(x, y, z) 905 | # relative pos - block position relatively to other shape blocks 906 | self.relativePos = minecraft.Vec3(x, y, z) 907 | # actual pos - actual block position in the world 908 | self.actualPos = minecraft.Vec3(x, y, z) 909 | 910 | #the tag system is used to give a particular block inside a shape meaning 911 | # e.g. for an animal shape you could tag the block which is its head 912 | self.tag = tag 913 | 914 | # the mc block object 915 | self.mcBlock = block.Block(blockType, blockData) 916 | 917 | def resetRelativePos(self): 918 | """ 919 | resets the relative position of the block back to its original position 920 | """ 921 | self.relativePos = self.originalPos.clone() 922 | 923 | def __hash__(self): 924 | return hash((self.actualPos.x, self.actualPos.y, self.actualPos.z, self.blockType, self.blockData)) 925 | 926 | def __eq__(self, other): 927 | if other is None: 928 | return False 929 | else: 930 | return (self.actualPos.x, self.actualPos.y, self.actualPos.z, self.blockType, self.blockData) == (other.actualPos.x, other.actualPos.y, other.actualPos.z, other.blockType, other.blockData) 931 | 932 | class MinecraftTurtle: 933 | """ 934 | MinecraftTurle - a graphics turtle, which can be used to create 'things' in Minecraft by 935 | controlling its position, angles and direction 936 | 937 | :param mcpi.minecraft.Minecraft mc: 938 | A Minecraft object which is connected to a world. 939 | 940 | :param mcpi.minecraft.Vec3 position: 941 | The position where the shape should be created, defaults to ``0,0,0``. 942 | """ 943 | 944 | SPEEDTIMES = {0: 0, 10: 0.1, 9: 0.2, 8: 0.3, 7: 0.4, 6: 0.5, 5: 0.6, 4: 0.7, 3: 0.8, 2: 0.9, 1: 1} 945 | 946 | def __init__(self, mc, position=minecraft.Vec3(0, 0, 0)): 947 | # set defaults 948 | self.mc = mc 949 | # start position 950 | self.startposition = position 951 | # set turtle position 952 | self.position = position 953 | # set turtle angles 954 | self.heading = 0 955 | self.verticalheading = 0 956 | # set pen down 957 | self._pendown = True 958 | # set pen block to black wool 959 | self._penblock = block.Block(block.WOOL.id, 15) 960 | # flying to true 961 | self.flying = True 962 | # set speed 963 | self.turtlespeed = 6 964 | # create turtle 965 | self.showturtle = True 966 | # create drawing object 967 | self.mcDrawing = MinecraftDrawing(self.mc) 968 | # set turtle block 969 | self.turtleblock = block.Block(block.DIAMOND_BLOCK.id) 970 | # draw turtle 971 | self._drawTurtle(int(self.position.x), int(self.position.y), int(self.position.y)) 972 | 973 | def forward(self, distance): 974 | """ 975 | move the turtle forward 976 | 977 | :param int distance: 978 | the number of blocks to move. 979 | """ 980 | # get end of line 981 | # x,y,z = self._findTargetBlock(self.position.x, self.position.y, self.position.z, self.heading, self.verticalheading, distance) 982 | x, y, z = self._findPointOnSphere(self.position.x, self.position.y, self.position.z, self.heading, self.verticalheading, distance) 983 | # move turtle forward 984 | self._moveTurtle(x, y, z) 985 | 986 | def backward(self, distance): 987 | """ 988 | move the turtle backward 989 | 990 | :param int distance: 991 | the number of blocks to move. 992 | """ 993 | # move turtle backward 994 | # get end of line 995 | # x,y,z = self._findTargetBlock(self.position.x, self.position.y, self.position.z, self.heading, self.verticalheading - 180, distance) 996 | x, y, z = self._findPointOnSphere(self.position.x, self.position.y, self.position.z, self.heading, self.verticalheading - 180, distance) 997 | # move turtle forward 998 | self._moveTurtle(x, y, z) 999 | 1000 | def _moveTurtle(self, x, y, z): 1001 | # get blocks between current position and next 1002 | targetX, targetY, targetZ = int(x), int(y), int(z) 1003 | # if walking, set target Y to be height of world 1004 | if not self.flying: 1005 | targetY = self.mc.getHeight(targetX, targetZ) 1006 | currentX, currentY, currentZ = int(self.position.x), int(self.position.y), int(self.position.z) 1007 | 1008 | # clear the turtle 1009 | if self.showturtle: 1010 | self._clearTurtle(currentX, currentY, currentZ) 1011 | 1012 | # if speed is 0 and flying, just draw the line, else animate it 1013 | if self.turtlespeed == 0 and self.flying: 1014 | # draw the line 1015 | if self._pendown: 1016 | self.mcDrawing.drawLine(currentX, currentY - 1, currentZ, targetX, targetY - 1, targetZ, self._penblock.id, self._penblock.data) 1017 | else: 1018 | blocksBetween = self.mcDrawing.getLine(currentX, currentY, currentZ, targetX, targetY, targetZ) 1019 | for blockBetween in blocksBetween: 1020 | # print blockBetween 1021 | # if walking update the y, to be the height of the world 1022 | if not self.flying: 1023 | blockBetween.y = self.mc.getHeight(blockBetween.x, blockBetween.z) 1024 | # draw the turtle 1025 | if self.showturtle: 1026 | self._drawTurtle(blockBetween.x, blockBetween.y, blockBetween.z) 1027 | # draw the pen 1028 | if self._pendown: 1029 | self.mcDrawing.drawPoint3d(blockBetween.x, blockBetween.y - 1, blockBetween.z, self._penblock.id, self._penblock.data) 1030 | # wait 1031 | time.sleep(self.SPEEDTIMES[self.turtlespeed]) 1032 | # clear the turtle 1033 | if self.showturtle: 1034 | self._clearTurtle(blockBetween.x, blockBetween.y, blockBetween.z) 1035 | 1036 | # update turtle's position to be the target 1037 | self.position.x, self.position.y, self.position.z = x, y, z 1038 | # draw turtle 1039 | if self.showturtle: 1040 | self._drawTurtle(targetX, targetY, targetZ) 1041 | 1042 | def right(self, angle): 1043 | """ 1044 | rotate the turtle right 1045 | 1046 | :param float angle: 1047 | the angle in degrees to rotate. 1048 | """ 1049 | # rotate turtle angle to the right 1050 | self.heading = self.heading + angle 1051 | if self.heading > 360: 1052 | self.heading = self.heading - 360 1053 | 1054 | def left(self, angle): 1055 | """ 1056 | rotate the turtle left 1057 | 1058 | :param float angle: 1059 | the angle in degrees to rotate. 1060 | """ 1061 | # rotate turtle angle to the left 1062 | self.heading = self.heading - angle 1063 | if self.heading < 0: 1064 | self.heading = self.heading + 360 1065 | 1066 | def up(self, angle): 1067 | """ 1068 | rotate the turtle up 1069 | 1070 | :param float angle: 1071 | the angle in degrees to rotate. 1072 | """ 1073 | # rotate turtle angle up 1074 | self.verticalheading = self.verticalheading + angle 1075 | if self.verticalheading > 360: 1076 | self.verticalheading = self.verticalheading - 360 1077 | # turn flying on 1078 | if not self.flying: 1079 | self.flying = True 1080 | 1081 | def down(self, angle): 1082 | """ 1083 | rotate the turtle down 1084 | 1085 | :param float angle: 1086 | the angle in degrees to rotate. 1087 | """ 1088 | # rotate turtle angle down 1089 | self.verticalheading = self.verticalheading - angle 1090 | if self.verticalheading < 0: 1091 | self.verticalheading = self.verticalheading + 360 1092 | # turn flying on 1093 | if not self.flying: 1094 | self.flying = True 1095 | 1096 | def setx(self, x): 1097 | """ 1098 | set the turtle's x position 1099 | 1100 | :param int x: 1101 | the x position. 1102 | """ 1103 | self.setposition(x, self.position.y, self.position.z) 1104 | 1105 | def sety(self, y): 1106 | """ 1107 | set the turtle's y position 1108 | 1109 | :param int y: 1110 | the y position. 1111 | """ 1112 | self.setposition(self.position.x, y, self.position.z) 1113 | 1114 | def setz(self, z): 1115 | """ 1116 | set the turtle's z position 1117 | 1118 | :param int z: 1119 | the z position. 1120 | """ 1121 | self.setposition(self.position.x, self.position.y, z) 1122 | 1123 | def setposition(self, x, y, z): 1124 | """ 1125 | set the turtle's position 1126 | 1127 | :param int x: 1128 | the x position. 1129 | 1130 | :param int y: 1131 | the y position. 1132 | 1133 | :param int z: 1134 | the z position. 1135 | """ 1136 | # clear the turtle 1137 | if self.showturtle: 1138 | self._clearTurtle(self.position.x, self.position.y, self.position.z) 1139 | # update the position 1140 | self.position.x = x 1141 | self.position.y = y 1142 | self.position.z = z 1143 | # draw the turtle 1144 | if self.showturtle: 1145 | self._drawTurtle(self.position.x, self.position.y, self.position.z) 1146 | 1147 | def setheading(self, angle): 1148 | """ 1149 | set the turtle's horizontal heading 1150 | 1151 | :param float angle: 1152 | the angle in degrees. 1153 | """ 1154 | self.heading = angle 1155 | 1156 | def setverticalheading(self, angle): 1157 | """ 1158 | set the turtle's verticle heading 1159 | 1160 | :param float angle: 1161 | the angle in degrees. 1162 | """ 1163 | self.verticalheading = angle 1164 | # turn flying on 1165 | if not self.flying: 1166 | self.flying = True 1167 | 1168 | def home(self): 1169 | """ 1170 | reset the turtle's position 1171 | """ 1172 | self.position.x = self.startposition.x 1173 | self.position.y = self.startposition.y 1174 | self.position.z = self.startposition.z 1175 | 1176 | def pendown(self): 1177 | """ 1178 | put the turtles pen down, show it will draw 1179 | """ 1180 | self._pendown = True 1181 | 1182 | def penup(self): 1183 | """ 1184 | put the turtles pen up, show it wont draw 1185 | """ 1186 | self._pendown = False 1187 | 1188 | def isdown(self): 1189 | """ 1190 | returns ``True`` if the pen is down 1191 | """ 1192 | return self.pendown 1193 | 1194 | def fly(self): 1195 | """ 1196 | sets the turtle to 'fly', i.e. not have to move along the ground. 1197 | """ 1198 | self.flying = True 1199 | 1200 | def walk(self): 1201 | """ 1202 | sets the turtle to 'walk', i.e. it has to move along the ground. 1203 | """ 1204 | self.flying = False 1205 | self.verticalheading = 0 1206 | 1207 | def penblock(self, blockId, blockData=0): 1208 | """ 1209 | set the block the turtle uses as its pen. 1210 | 1211 | :param int blockType: 1212 | The block id. 1213 | 1214 | :param int blockData: 1215 | The block data value, defaults to ``0``. 1216 | """ 1217 | self._penblock = block.Block(blockId, blockData) 1218 | 1219 | def speed(self, turtlespeed): 1220 | """ 1221 | set the turtle's speed. 1222 | 1223 | :param int turtlespeed: 1224 | ``1`` - ``10``, 1 being the slowest, 10 being the fastest, defaults to ``6``. 1225 | When set to ``0`` the turtle draws instantaneously. 1226 | """ 1227 | self.turtlespeed = turtlespeed 1228 | 1229 | def _drawTurtle(self, x, y, z): 1230 | # draw turtle 1231 | self.mcDrawing.drawPoint3d(x, y, z, self.turtleblock.id, self.turtleblock.data) 1232 | lastDrawnTurtle = minecraft.Vec3(x, y, z) 1233 | 1234 | def _clearTurtle(self, x, y, z): 1235 | # clear turtle 1236 | self.mcDrawing.drawPoint3d(x, y, z, block.AIR.id) 1237 | 1238 | def _findTargetBlock(self, turtleX, turtleY, turtleZ, heading, verticalheading, distance): 1239 | x, y, z = self._findPointOnSphere(turtleX, turtleY, turtleZ, heading, verticalheading, distance) 1240 | x = int(round(x, 0)) 1241 | y = int(round(y, 0)) 1242 | z = int(round(z, 0)) 1243 | return x, y, z 1244 | 1245 | def _findPointOnSphere(self, cx, cy, cz, horizontalAngle, verticalAngle, radius): 1246 | x = cx + (radius * (math.cos(math.radians(verticalAngle)) * math.cos(math.radians(horizontalAngle)))) 1247 | y = cy + (radius * (math.sin(math.radians(verticalAngle)))) 1248 | z = cz + (radius * (math.cos(math.radians(verticalAngle)) * math.sin(math.radians(horizontalAngle)))) 1249 | return x, y, z 1250 | 1251 | def _roundXYZ(x, y, z): 1252 | return int(round(x, 0)), int(round(y, 0)), int(round(z, 0)) 1253 | 1254 | def _roundVec3(position): 1255 | return minecraft.vec3(int(position.x), int(position.y), int(position.z)) 1256 | 1257 | -------------------------------------------------------------------------------- /script.py: -------------------------------------------------------------------------------- 1 | import mcpi.minecraft as minecraft 2 | import time 3 | 4 | # Connect to minecraft server 127.0.0.1 as player 'steve'. Replace with your own IP/name! 5 | mc = minecraft.Minecraft.create(address="127.0.0.1", name="steve") 6 | 7 | # PUT CODE HERE. 8 | # Checkout the /examples directory with ready-to-go scripts, all you need to do is update your IP and name in them! 9 | 10 | --------------------------------------------------------------------------------