void skeletonMoveBodyparts(Entity *my, stat_t *myStats, double dist) { node_t *node; Entity *entity = NULL, *entity2 = NULL; Entity *rightbody = NULL; Entity *weaponarm=NULL; int bodypart; bool wearingring=FALSE; // set invisibility if( multiplayer != CLIENT ) { if( myStats->ring != NULL ) if( myStats->ring->type == RING_INVISIBILITY ) wearingring = TRUE; if( myStats->cloak != NULL ) if( myStats->cloak->type == CLOAK_INVISIBILITY ) wearingring = TRUE; if( myStats->EFFECTS[EFF_INVISIBLE] == TRUE || wearingring==TRUE ) { my->flags[INVISIBLE] = TRUE; my->flags[BLOCKSIGHT] = FALSE; bodypart=0; for(node = my->children.first; node!=NULL; node=node->next) { if( bodypart<2 ) { bodypart++; continue; } if( bodypart>=7 ) { break; } entity = (Entity *)node->element; if( !entity->flags[INVISIBLE] ) { entity->flags[INVISIBLE] = TRUE; serverUpdateEntityBodypart(my,bodypart); } bodypart++; } } else { my->flags[INVISIBLE] = FALSE; my->flags[BLOCKSIGHT] = TRUE; bodypart=0; for(node = my->children.first; node!=NULL; node=node->next) { if( bodypart<2 ) { bodypart++; continue; } if( bodypart>=7 ) { break; } entity = (Entity *)node->element; if( entity->flags[INVISIBLE] ) { entity->flags[INVISIBLE] = FALSE; serverUpdateEntityBodypart(my,bodypart); } bodypart++; } } // sleeping if( myStats->EFFECTS[EFF_ASLEEP] ) { my->z = 2; my->pitch = PI/4; } else { my->z = -.5; my->pitch = 0; } } //Move bodyparts for(bodypart=0, node = my->children.first; node!=NULL; node=node->next, bodypart++) { if( bodypart<2 ) { continue; } entity = (Entity *)node->element; entity->x = my->x; entity->y = my->y; entity->z = my->z; entity->yaw = my->yaw; if( bodypart==3||bodypart==6 ) { if( bodypart==3 ) rightbody = (Entity *)node->next->element; node_t *shieldNode = list_Node(&my->children,7); if( shieldNode ) { Entity *shield = (Entity *)shieldNode->element; if( dist>0.1 && (bodypart!=6||shield->flags[INVISIBLE]) ) { if( !rightbody->skill[0] ) { entity->pitch -= dist*SKELETONWALKSPEED; if( entity->pitch < -PI/4.0 ) { entity->pitch = -PI/4.0; if(bodypart==3) { entity->skill[0]=1; if( dist>.1 ) playSoundEntityLocal(my,95,32); } } } else { entity->pitch += dist*SKELETONWALKSPEED; if( entity->pitch > PI/4.0 ) { entity->pitch = PI/4.0; if(bodypart==3) { entity->skill[0]=0; if( dist>.1 ) playSoundEntityLocal(my,95,32); } } } } else { if( entity->pitch < 0 ) { entity->pitch += 1/fmax(dist*.1,10.0); if( entity->pitch > 0 ) entity->pitch=0; } else if( entity->pitch > 0 ) { entity->pitch -= 1/fmax(dist*.1,10.0); if( entity->pitch < 0 ) entity->pitch=0; } } } } else if( bodypart==4||bodypart==5||bodypart==9 ) { if( bodypart==5 ) { weaponarm = entity; if( MONSTER_ATTACK == 1 ) { // vertical chop if( MONSTER_ATTACKTIME == 0 ) { MONSTER_ARMBENDED = 0; MONSTER_WEAPONYAW = 0; entity->pitch = -3*PI/4; entity->roll = 0; } else { if( entity->pitch >= -PI/2 ) MONSTER_ARMBENDED = 1; if( entity->pitch >= PI/4 ) { entity->skill[0] = rightbody->skill[0]; MONSTER_WEAPONYAW = 0; entity->pitch = rightbody->pitch; entity->roll = 0; MONSTER_ARMBENDED = 0; MONSTER_ATTACK = 0; } else { entity->pitch += .25; } } } else if( MONSTER_ATTACK == 2 ) { // horizontal chop if( MONSTER_ATTACKTIME == 0 ) { MONSTER_ARMBENDED = 1; MONSTER_WEAPONYAW = -3*PI/4; entity->pitch = 0; entity->roll = -PI/2; } else { if( MONSTER_WEAPONYAW >= PI/8 ) { entity->skill[0] = rightbody->skill[0]; MONSTER_WEAPONYAW = 0; entity->pitch = rightbody->pitch; entity->roll = 0; MONSTER_ARMBENDED = 0; MONSTER_ATTACK = 0; } else { MONSTER_WEAPONYAW += .25; } } } else if( MONSTER_ATTACK == 3 ) { // stab if( MONSTER_ATTACKTIME == 0 ) { MONSTER_ARMBENDED = 0; MONSTER_WEAPONYAW = 0; entity->pitch = 2*PI/3; entity->roll = 0; } else { if( MONSTER_ATTACKTIME >= 5 ) { MONSTER_ARMBENDED = 1; entity->pitch = -PI/6; } if( MONSTER_ATTACKTIME >= 10 ) { entity->skill[0] = rightbody->skill[0]; MONSTER_WEAPONYAW = 0; entity->pitch = rightbody->pitch; entity->roll = 0; MONSTER_ARMBENDED = 0; MONSTER_ATTACK = 0; } } } } else if( bodypart==9 ) { entity->pitch=entity->fskill[0]; } if( bodypart!=5 || (MONSTER_ATTACK==0 && MONSTER_ATTACKTIME==0) ) { if( dist>0.1 ) { if( entity->skill[0] ) { entity->pitch -= dist*SKELETONWALKSPEED; if( entity->pitch < -PI/4.0 ) { entity->skill[0]=0; entity->pitch = -PI/4.0; } } else { entity->pitch += dist*SKELETONWALKSPEED; if( entity->pitch > PI/4.0 ) { entity->skill[0]=1; entity->pitch = PI/4.0; } } } else { if( entity->pitch < 0 ) { entity->pitch += 1/fmax(dist*.1,10.0); if( entity->pitch > 0 ) entity->pitch=0; } else if( entity->pitch > 0 ) { entity->pitch -= 1/fmax(dist*.1,10.0); if( entity->pitch < 0 ) entity->pitch=0; } } } if( bodypart==9 ) { entity->fskill[0]=entity->pitch; entity->roll=my->roll-fabs(entity->pitch)/2; entity->pitch=0; } } switch( bodypart ) { // torso case 2: if( multiplayer!=CLIENT ) { if( myStats->breastplate == NULL ) { entity->sprite = 230; } else { entity->sprite = itemModel(myStats->breastplate); } if( multiplayer==SERVER ) { // update sprites for clients if( entity->skill[10]!=entity->sprite ) { entity->skill[10]=entity->sprite; serverUpdateEntityBodypart(my,bodypart); } if( entity->uid%(TICKS_PER_SECOND*10) == ticks%(TICKS_PER_SECOND*10) ) { serverUpdateEntityBodypart(my,bodypart); } } } entity->x-=.25*cos(my->yaw); entity->y-=.25*sin(my->yaw); entity->z+=2; break; // right leg case 3: entity->sprite = 236; entity->x+=1*cos(my->yaw+PI/2)+.25*cos(my->yaw); entity->y+=1*sin(my->yaw+PI/2)+.25*sin(my->yaw); entity->z+=4; if( my->z >= 1.9 && my->z <= 2.1 ) { entity->yaw += PI/8; entity->pitch = -PI/2; } break; // left leg case 4: entity->sprite = 235; entity->x-=1*cos(my->yaw+PI/2)-.25*cos(my->yaw); entity->y-=1*sin(my->yaw+PI/2)-.25*sin(my->yaw); entity->z+=4; if( my->z >= 1.9 && my->z <= 2.1 ) { entity->yaw -= PI/8; entity->pitch = -PI/2; } break; // right arm case 5: { entity->sprite = 233; node_t *weaponNode = list_Node(&my->children,7); if( weaponNode ) { Entity *weapon = (Entity *)weaponNode->element; if( !MONSTER_ARMBENDED ) entity->sprite += (weapon->flags[INVISIBLE]!=TRUE); if( weapon->flags[INVISIBLE] || MONSTER_ARMBENDED ) { entity->focalx = limbs[SKELETON][4][0]; // 0 entity->focaly = limbs[SKELETON][4][1]; // 0 entity->focalz = limbs[SKELETON][4][2]; // 2 } else { entity->focalx = limbs[SKELETON][4][0] + 1; // 1 entity->focaly = limbs[SKELETON][4][1]; // 0 entity->focalz = limbs[SKELETON][4][2] - 1; // 1 } } entity->x+=1.75*cos(my->yaw+PI/2)-.20*cos(my->yaw); entity->y+=1.75*sin(my->yaw+PI/2)-.20*sin(my->yaw); entity->z+=.5; entity->yaw += MONSTER_WEAPONYAW; if( my->z >= 1.9 && my->z <= 2.1 ) { entity->pitch = 0; } break; // left arm } case 6: { entity->sprite = 231; node_t *shieldNode = list_Node(&my->children,8); if( shieldNode ) { Entity *shield = (Entity *)shieldNode->element; entity->sprite += (shield->flags[INVISIBLE]!=TRUE); if( shield->flags[INVISIBLE] ) { entity->focalx = limbs[SKELETON][5][0]; // 0 entity->focaly = limbs[SKELETON][5][1]; // 0 entity->focalz = limbs[SKELETON][5][2]; // 2 } else { entity->focalx = limbs[SKELETON][5][0] + 1; // 1 entity->focaly = limbs[SKELETON][5][1]; // 0 entity->focalz = limbs[SKELETON][5][2] - 1; // 1 } } entity->x-=1.75*cos(my->yaw+PI/2)+.20*cos(my->yaw); entity->y-=1.75*sin(my->yaw+PI/2)+.20*sin(my->yaw); entity->z+=.5; if( my->z >= 1.9 && my->z <= 2.1 ) { entity->pitch = 0; } break; } // weapon case 7: if( multiplayer!=CLIENT ) { if( myStats->weapon == NULL || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) { entity->flags[INVISIBLE]=TRUE; } else { entity->sprite = itemModel(myStats->weapon); if( itemCategory(myStats->weapon) == SPELLBOOK ) entity->flags[INVISIBLE]=TRUE; else entity->flags[INVISIBLE]=FALSE; } if( multiplayer==SERVER ) { // update sprites for clients if( entity->skill[10]!=entity->sprite ) { entity->skill[10]=entity->sprite; serverUpdateEntityBodypart(my,bodypart); } if( entity->skill[11] != entity->flags[INVISIBLE] ) { entity->skill[11] = entity->flags[INVISIBLE]; serverUpdateEntityBodypart(my,bodypart); } if( entity->uid%(TICKS_PER_SECOND*10) == ticks%(TICKS_PER_SECOND*10) ) { serverUpdateEntityBodypart(my,bodypart); } } } if( weaponarm != NULL ) { if( entity->flags[INVISIBLE] != TRUE ) { if( entity->sprite == items[SHORTBOW].index ) { entity->x=weaponarm->x-.5*cos(weaponarm->yaw); entity->y=weaponarm->y-.5*sin(weaponarm->yaw); entity->z=weaponarm->z+1; entity->pitch=weaponarm->pitch+.25; } else if( entity->sprite == items[ARTIFACT_BOW].index ) { entity->x=weaponarm->x-1.5*cos(weaponarm->yaw); entity->y=weaponarm->y-1.5*sin(weaponarm->yaw); entity->z=weaponarm->z+2; entity->pitch=weaponarm->pitch+.25; } else if( entity->sprite == items[CROSSBOW].index ) { entity->x=weaponarm->x; entity->y=weaponarm->y; entity->z=weaponarm->z+1; entity->pitch=weaponarm->pitch; } else { entity->x=weaponarm->x+.5*cos(weaponarm->yaw)*(MONSTER_ATTACK==0); entity->y=weaponarm->y+.5*sin(weaponarm->yaw)*(MONSTER_ATTACK==0); entity->z=weaponarm->z-.5*(MONSTER_ATTACK==0); entity->pitch=weaponarm->pitch+.25*(MONSTER_ATTACK==0); } } entity->yaw=weaponarm->yaw; entity->roll=weaponarm->roll; if( !MONSTER_ARMBENDED ) { entity->focalx = limbs[SKELETON][6][0]; // 2.5 if( entity->sprite == items[CROSSBOW].index ) entity->focalx += 2; entity->focaly = limbs[SKELETON][6][1]; // 0 entity->focalz = limbs[SKELETON][6][2]; // -.5 } else { entity->focalx = limbs[SKELETON][6][0] + 1; // 3.5 entity->focaly = limbs[SKELETON][6][1]; // 0 entity->focalz = limbs[SKELETON][6][2] - 2; // -2.5 entity->yaw -= sin(weaponarm->roll)*PI/2; entity->pitch += cos(weaponarm->roll)*PI/2; } } break; // shield case 8: if( multiplayer!=CLIENT ) { if( myStats->shield == NULL ) { entity->flags[INVISIBLE]=TRUE; entity->sprite = 0; } else { entity->flags[INVISIBLE]=FALSE; entity->sprite = itemModel(myStats->shield); } if( myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) { entity->flags[INVISIBLE]=TRUE; } if( multiplayer==SERVER ) { // update sprites for clients if( entity->skill[10]!=entity->sprite ) { entity->skill[10]=entity->sprite; serverUpdateEntityBodypart(my,bodypart); } if( entity->skill[11] != entity->flags[INVISIBLE] ) { entity->skill[11] = entity->flags[INVISIBLE]; serverUpdateEntityBodypart(my,bodypart); } if( entity->uid%(TICKS_PER_SECOND*10) == ticks%(TICKS_PER_SECOND*10) ) { serverUpdateEntityBodypart(my,bodypart); } } } entity->x-=2.5*cos(my->yaw+PI/2)+.20*cos(my->yaw); entity->y-=2.5*sin(my->yaw+PI/2)+.20*sin(my->yaw); entity->z+=2.5; if( entity->sprite == items[TOOL_TORCH].index ) { entity2 = spawnFlame(entity); entity2->x += 2*cos(my->yaw); entity2->y += 2*sin(my->yaw); entity2->z -= 2; } else if( entity->sprite == items[TOOL_LANTERN].index ) { entity->z += 2; entity2 = spawnFlame(entity); entity2->x += 2*cos(my->yaw); entity2->y += 2*sin(my->yaw); entity2->z += 1; } break; // cloak case 9: if( multiplayer!=CLIENT ) { if( myStats->cloak == NULL || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) { entity->flags[INVISIBLE]=TRUE; } else { entity->flags[INVISIBLE]=FALSE; entity->sprite = itemModel(myStats->cloak); } if( multiplayer==SERVER ) { // update sprites for clients if( entity->skill[10]!=entity->sprite ) { entity->skill[10]=entity->sprite; serverUpdateEntityBodypart(my,bodypart); } if( entity->skill[11] != entity->flags[INVISIBLE] ) { entity->skill[11] = entity->flags[INVISIBLE]; serverUpdateEntityBodypart(my,bodypart); } if( entity->uid%(TICKS_PER_SECOND*10) == ticks%(TICKS_PER_SECOND*10) ) { serverUpdateEntityBodypart(my,bodypart); } } } entity->x-=cos(my->yaw); entity->y-=sin(my->yaw); entity->yaw+=PI/2; break; // helm case 10: entity->focalx = limbs[SKELETON][9][0]; // 0 entity->focaly = limbs[SKELETON][9][1]; // 0 entity->focalz = limbs[SKELETON][9][2]; // -2 entity->pitch = my->pitch; entity->roll = 0; if( multiplayer!=CLIENT ) { entity->sprite = itemModel(myStats->helmet); if( myStats->helmet == NULL || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) { entity->flags[INVISIBLE]=TRUE; } else { entity->flags[INVISIBLE]=FALSE; } if( multiplayer==SERVER ) { // update sprites for clients if( entity->skill[10]!=entity->sprite ) { entity->skill[10]=entity->sprite; serverUpdateEntityBodypart(my,bodypart); } if( entity->skill[11] != entity->flags[INVISIBLE] ) { entity->skill[11] = entity->flags[INVISIBLE]; serverUpdateEntityBodypart(my,bodypart); } if( entity->uid%(TICKS_PER_SECOND*10) == ticks%(TICKS_PER_SECOND*10) ) { serverUpdateEntityBodypart(my,bodypart); } } } if( entity->sprite != items[STEEL_HELM].index ) { if( entity->sprite == items[HAT_PHRYGIAN].index ) { entity->focalx = limbs[SKELETON][9][0] - .5; // -.5 entity->focaly = limbs[SKELETON][9][1] - 3.25; // -3.25 entity->focalz = limbs[SKELETON][9][2] + 2.5; // .5 entity->roll=PI/2; } else if( entity->sprite >= items[HAT_HOOD].index && entity->sprite < items[HAT_HOOD].index+items[HAT_HOOD].variations ) { entity->focalx = limbs[SKELETON][9][0] - .5; // -.5 entity->focaly = limbs[SKELETON][9][1] - 2.5; // -2.5 entity->focalz = limbs[SKELETON][9][2] + 2.5; // 2.5 entity->roll=PI/2; } else if( entity->sprite == items[HAT_WIZARD].index ) { entity->focalx = limbs[SKELETON][9][0]; // 0 entity->focaly = limbs[SKELETON][9][1] - 4.75; // -4.75 entity->focalz = limbs[SKELETON][9][2] + .5; // .5 entity->roll=PI/2; } else if( entity->sprite == items[HAT_JESTER].index ) { entity->focalx = limbs[SKELETON][9][0]; // 0 entity->focaly = limbs[SKELETON][9][1] - 4.75; // -4.75 entity->focalz = limbs[SKELETON][9][2] + .5; // .5 entity->roll=PI/2; } } else { my->flags[INVISIBLE]=TRUE; } break; // mask case 11: entity->focalx = limbs[SKELETON][10][0]; // 0 entity->focaly = limbs[SKELETON][10][1]; // 0 entity->focalz = limbs[SKELETON][10][2]; // .5 entity->pitch = my->pitch; entity->roll=PI/2; if( multiplayer!=CLIENT ) { if( myStats->mask == NULL || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) { entity->flags[INVISIBLE]=TRUE; } else { entity->flags[INVISIBLE]=FALSE; } if( myStats->mask != NULL ) { if( myStats->mask->type == TOOL_GLASSES ) { entity->sprite = 165; // GlassesWorn.vox } else { entity->sprite = itemModel(myStats->mask); } } if( multiplayer==SERVER ) { // update sprites for clients if( entity->skill[10]!=entity->sprite ) { entity->skill[10]=entity->sprite; serverUpdateEntityBodypart(my,bodypart); } if( entity->skill[11] != entity->flags[INVISIBLE] ) { entity->skill[11] = entity->flags[INVISIBLE]; serverUpdateEntityBodypart(my,bodypart); } if( entity->uid%(TICKS_PER_SECOND*10) == ticks%(TICKS_PER_SECOND*10) ) { serverUpdateEntityBodypart(my,bodypart); } } } if( entity->sprite != 165 ) { entity->focalx = limbs[SKELETON][10][0] + .35; // .35 entity->focaly = limbs[SKELETON][10][1] - 2; // -2 entity->focalz = limbs[SKELETON][10][2]; // .5 } else { entity->focalx = limbs[SKELETON][10][0] + .25; // .25 entity->focaly = limbs[SKELETON][10][1] - 2.25; // -2.25 entity->focalz = limbs[SKELETON][10][2]; // .5 } break; } } if( MONSTER_ATTACK != 0 ) MONSTER_ATTACKTIME++; else MONSTER_ATTACKTIME=0; }
void humanMoveBodyparts(Entity* my, Stat* myStats, double dist) { node_t* node; Entity* entity = nullptr, *entity2 = nullptr; Entity* rightbody = nullptr; Entity* weaponarm = nullptr; int bodypart; bool wearingring = false; // set invisibility //TODO: isInvisible()? if ( multiplayer != CLIENT ) { if ( myStats->ring != nullptr ) if ( myStats->ring->type == RING_INVISIBILITY ) { wearingring = true; } if ( myStats->cloak != nullptr ) if ( myStats->cloak->type == CLOAK_INVISIBILITY ) { wearingring = true; } if ( myStats->EFFECTS[EFF_INVISIBLE] == true || wearingring == true ) { my->flags[INVISIBLE] = true; my->flags[BLOCKSIGHT] = false; bodypart = 0; for (node = my->children.first; node != nullptr; node = node->next) { if ( bodypart < 2 ) { bodypart++; continue; } if ( bodypart >= 7 ) { break; } entity = (Entity*)node->element; if ( !entity->flags[INVISIBLE] ) { entity->flags[INVISIBLE] = true; serverUpdateEntityBodypart(my, bodypart); } bodypart++; } } else { my->flags[INVISIBLE] = false; my->flags[BLOCKSIGHT] = true; bodypart = 0; for (node = my->children.first; node != nullptr; node = node->next) { if ( bodypart < 2 ) { bodypart++; continue; } if ( bodypart >= 7 ) { break; } entity = (Entity*)node->element; if ( entity->flags[INVISIBLE] ) { entity->flags[INVISIBLE] = false; serverUpdateEntityBodypart(my, bodypart); serverUpdateEntityFlag(my, INVISIBLE); } bodypart++; } } // sleeping if ( myStats->EFFECTS[EFF_ASLEEP] ) { my->z = 1.5; my->pitch = PI / 4; } else { my->z = -1; if ( my->monsterAttack == 0 ) { my->pitch = 0; } } // levitation bool levitating = isLevitating(myStats); if ( levitating ) { my->z -= 1; // floating } } Entity* shieldarm = nullptr; // move bodyparts for (bodypart = 0, node = my->children.first; node != nullptr; node = node->next, bodypart++) { if ( bodypart < 2 ) { if ( multiplayer == CLIENT ) { for ( int i = LIMB_HUMANOID_TORSO; i <= LIMB_HUMANOID_LEFTARM; i++ ) { my->humanSetLimbsClient(i); } } continue; } entity = (Entity*)node->element; entity->x = my->x; entity->y = my->y; entity->z = my->z; if ( MONSTER_ATTACK == MONSTER_POSE_MAGIC_WINDUP1 && bodypart == LIMB_HUMANOID_RIGHTARM ) { // don't let the creatures's yaw move the casting arm } else { entity->yaw = my->yaw; } if ( bodypart == LIMB_HUMANOID_RIGHTLEG || bodypart == LIMB_HUMANOID_LEFTARM ) { my->humanoidAnimateWalk(entity, node, bodypart, HUMANWALKSPEED, dist, 0.4); } else if ( bodypart == LIMB_HUMANOID_LEFTLEG || bodypart == LIMB_HUMANOID_RIGHTARM || bodypart == LIMB_HUMANOID_CLOAK ) { // left leg, right arm, cloak. if ( bodypart == LIMB_HUMANOID_RIGHTARM ) { weaponarm = entity; if ( my->monsterAttack > 0 ) { my->handleWeaponArmAttack(weaponarm); } } else if ( bodypart == LIMB_HUMANOID_CLOAK ) { entity->pitch = entity->fskill[0]; } my->humanoidAnimateWalk(entity, node, bodypart, HUMANWALKSPEED, dist, 0.4); if ( bodypart == LIMB_HUMANOID_CLOAK ) { entity->fskill[0] = entity->pitch; entity->roll = my->roll - fabs(entity->pitch) / 2; entity->pitch = 0; } } switch ( bodypart ) { // torso case LIMB_HUMANOID_TORSO: if ( multiplayer != CLIENT ) { if ( myStats->breastplate == nullptr ) { switch ( myStats->appearance / 6 ) { case 1: entity->sprite = 334 + 13 * myStats->sex; break; case 2: entity->sprite = 360 + 13 * myStats->sex; break; default: entity->sprite = 106 + 12 * myStats->sex; break; } } else { entity->sprite = itemModel(myStats->breastplate); } if ( multiplayer == SERVER ) { // update sprites for clients if ( entity->skill[10] != entity->sprite ) { entity->skill[10] = entity->sprite; serverUpdateEntityBodypart(my, bodypart); } if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) ) { serverUpdateEntityBodypart(my, bodypart); } } } entity->x -= .25 * cos(my->yaw); entity->y -= .25 * sin(my->yaw); entity->z += 2.5; break; // right leg case LIMB_HUMANOID_RIGHTLEG: if ( multiplayer != CLIENT ) { if ( myStats->shoes == nullptr ) { switch ( myStats->appearance / 6 ) { case 1: entity->sprite = 335 + 13 * myStats->sex; break; case 2: entity->sprite = 361 + 13 * myStats->sex; break; default: entity->sprite = 107 + 12 * myStats->sex; break; } } else { my->setBootSprite(entity, SPRITE_BOOT_RIGHT_OFFSET); } if ( multiplayer == SERVER ) { // update sprites for clients if ( entity->skill[10] != entity->sprite ) { entity->skill[10] = entity->sprite; serverUpdateEntityBodypart(my, bodypart); } if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) ) { serverUpdateEntityBodypart(my, bodypart); } } } entity->x += 1 * cos(my->yaw + PI / 2) + .25 * cos(my->yaw); entity->y += 1 * sin(my->yaw + PI / 2) + .25 * sin(my->yaw); entity->z += 5; if ( my->z >= 1.4 && my->z <= 1.6 ) { entity->yaw += PI / 8; entity->pitch = -PI / 2; } break; // left leg case LIMB_HUMANOID_LEFTLEG: if ( multiplayer != CLIENT ) { if ( myStats->shoes == nullptr ) { switch ( myStats->appearance / 6 ) { case 1: entity->sprite = 336 + 13 * myStats->sex; break; case 2: entity->sprite = 362 + 13 * myStats->sex; break; default: entity->sprite = 108 + 12 * myStats->sex; break; } } else { my->setBootSprite(entity, SPRITE_BOOT_LEFT_OFFSET); } if ( multiplayer == SERVER ) { // update sprites for clients if ( entity->skill[10] != entity->sprite ) { entity->skill[10] = entity->sprite; serverUpdateEntityBodypart(my, bodypart); } if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) ) { serverUpdateEntityBodypart(my, bodypart); } } } entity->x -= 1 * cos(my->yaw + PI / 2) - .25 * cos(my->yaw); entity->y -= 1 * sin(my->yaw + PI / 2) - .25 * sin(my->yaw); entity->z += 5; if ( my->z >= 1.4 && my->z <= 1.6 ) { entity->yaw -= PI / 8; entity->pitch = -PI / 2; } break; // right arm case LIMB_HUMANOID_RIGHTARM: { if ( multiplayer != CLIENT ) { if ( myStats->gloves == nullptr ) { switch ( myStats->appearance / 6 ) { case 1: entity->sprite = 337 + 13 * myStats->sex; break; case 2: entity->sprite = 363 + 13 * myStats->sex; break; default: entity->sprite = 109 + 12 * myStats->sex; break; } } else { if ( setGloveSprite(myStats, entity, SPRITE_GLOVE_RIGHT_OFFSET) != 0 ) { // successfully set sprite for the human model } } if ( multiplayer == SERVER ) { // update sprites for clients if ( entity->skill[10] != entity->sprite ) { entity->skill[10] = entity->sprite; serverUpdateEntityBodypart(my, bodypart); } if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) ) { serverUpdateEntityBodypart(my, bodypart); } } } if ( multiplayer == CLIENT ) { if ( entity->skill[7] == 0 ) { if ( entity->sprite >= 109 && entity->sprite <= 110 ) { // these are the default arms. // chances are they may be wrong if sent by the server, } else { // otherwise we're being sent gloves armor etc so it's probably right. entity->skill[7] = entity->sprite; } } if ( entity->skill[7] == 0 ) { // we set this ourselves until proper initialisation. my->humanSetLimbsClient(bodypart); } else { entity->sprite = entity->skill[7]; } } node_t* tempNode = list_Node(&my->children, LIMB_HUMANOID_WEAPON); if ( tempNode ) { Entity* weapon = (Entity*)tempNode->element; if ( MONSTER_ARMBENDED || (weapon->flags[INVISIBLE] && my->monsterState != MONSTER_STATE_ATTACK) ) { // if weapon invisible and I'm not attacking, relax arm. entity->focalx = limbs[HUMAN][4][0]; // 0 entity->focaly = limbs[HUMAN][4][1]; // 0 entity->focalz = limbs[HUMAN][4][2]; // 1.5 } else { // else flex arm. entity->focalx = limbs[HUMAN][4][0] + 0.75; entity->focaly = limbs[HUMAN][4][1]; entity->focalz = limbs[HUMAN][4][2] - 0.75; entity->sprite += 2; } } entity->x += 2.5 * cos(my->yaw + PI / 2) - .20 * cos(my->yaw); entity->y += 2.5 * sin(my->yaw + PI / 2) - .20 * sin(my->yaw); entity->z += 1.5; entity->yaw += MONSTER_WEAPONYAW; if ( my->z >= 1.4 && my->z <= 1.6 ) { entity->pitch = 0; } break; } // left arm case LIMB_HUMANOID_LEFTARM: { shieldarm = entity; if ( multiplayer != CLIENT ) { if ( myStats->gloves == nullptr ) { switch ( myStats->appearance / 6 ) { case 1: entity->sprite = 338 + 13 * myStats->sex; break; case 2: entity->sprite = 364 + 13 * myStats->sex; break; default: entity->sprite = 110 + 12 * myStats->sex; break; } } else { if ( setGloveSprite(myStats, entity, SPRITE_GLOVE_LEFT_OFFSET) != 0 ) { // successfully set sprite for the human model } } if ( multiplayer == SERVER ) { // update sprites for clients if ( entity->skill[10] != entity->sprite ) { entity->skill[10] = entity->sprite; serverUpdateEntityBodypart(my, bodypart); } if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) ) { serverUpdateEntityBodypart(my, bodypart); } } } if ( multiplayer == CLIENT ) { if ( entity->skill[7] == 0 ) { if ( entity->sprite >= 109 && entity->sprite <= 110 ) { // these are the default arms. // chances are they may be wrong if sent by the server, } else { // otherwise we're being sent gloves armor etc so it's probably right. entity->skill[7] = entity->sprite; } } if ( entity->skill[7] == 0 ) { // we set this ourselves until proper initialisation. my->humanSetLimbsClient(bodypart); } else { entity->sprite = entity->skill[7]; } } node_t* tempNode = list_Node(&my->children, LIMB_HUMANOID_SHIELD); if ( tempNode ) { Entity* shield = (Entity*)tempNode->element; if ( shield->flags[INVISIBLE] && (my->monsterState != MONSTER_STATE_ATTACK) ) { // if shield invisible and I'm not attacking, relax arm. entity->focalx = limbs[HUMAN][5][0]; // 0 entity->focaly = limbs[HUMAN][5][1]; // 0 entity->focalz = limbs[HUMAN][5][2]; // 1.5 } else { // else flex arm. entity->focalx = limbs[HUMAN][5][0] + 0.75; entity->focaly = limbs[HUMAN][5][1]; entity->focalz = limbs[HUMAN][5][2] - 0.75; entity->sprite += 2; } } entity->x -= 2.5 * cos(my->yaw + PI / 2) + .20 * cos(my->yaw); entity->y -= 2.5 * sin(my->yaw + PI / 2) + .20 * sin(my->yaw); entity->z += 1.5; if ( my->z >= 1.4 && my->z <= 1.6 ) { entity->pitch = 0; } if ( my->monsterDefend && my->monsterAttack == 0 ) { MONSTER_SHIELDYAW = PI / 5; } else { MONSTER_SHIELDYAW = 0; } entity->yaw += MONSTER_SHIELDYAW; break; } // weapon case LIMB_HUMANOID_WEAPON: if ( multiplayer != CLIENT ) { if ( myStats->weapon == nullptr || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) //TODO: isInvisible()? { entity->flags[INVISIBLE] = true; } else { entity->sprite = itemModel(myStats->weapon); if ( itemCategory(myStats->weapon) == SPELLBOOK ) { entity->flags[INVISIBLE] = true; } else { entity->flags[INVISIBLE] = false; } } if ( multiplayer == SERVER ) { // update sprites for clients if ( entity->skill[10] != entity->sprite ) { entity->skill[10] = entity->sprite; serverUpdateEntityBodypart(my, bodypart); } if ( entity->skill[11] != entity->flags[INVISIBLE] ) { entity->skill[11] = entity->flags[INVISIBLE]; serverUpdateEntityBodypart(my, bodypart); } if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) ) { serverUpdateEntityBodypart(my, bodypart); } } } else { if ( entity->sprite <= 0 ) { entity->flags[INVISIBLE] = true; } } if ( weaponarm != nullptr ) { my->handleHumanoidWeaponLimb(entity, weaponarm); } break; // shield case LIMB_HUMANOID_SHIELD: if ( multiplayer != CLIENT ) { if ( myStats->shield == nullptr ) { entity->flags[INVISIBLE] = true; entity->sprite = 0; } else { entity->flags[INVISIBLE] = false; entity->sprite = itemModel(myStats->shield); } if ( myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) //TODO: isInvisible()? { entity->flags[INVISIBLE] = true; } if ( multiplayer == SERVER ) { // update sprites for clients if ( entity->skill[10] != entity->sprite ) { entity->skill[10] = entity->sprite; serverUpdateEntityBodypart(my, bodypart); } if ( entity->skill[11] != entity->flags[INVISIBLE] ) { entity->skill[11] = entity->flags[INVISIBLE]; serverUpdateEntityBodypart(my, bodypart); } if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) ) { serverUpdateEntityBodypart(my, bodypart); } } } else { if ( entity->sprite <= 0 ) { entity->flags[INVISIBLE] = true; } } entity->x -= 2.5 * cos(my->yaw + PI / 2) + .20 * cos(my->yaw); entity->y -= 2.5 * sin(my->yaw + PI / 2) + .20 * sin(my->yaw); entity->z += 2.5; entity->yaw = shieldarm->yaw; entity->roll = 0; entity->pitch = 0; if ( entity->sprite == items[TOOL_TORCH].index ) { entity2 = spawnFlame(entity, SPRITE_FLAME); entity2->x += 2 * cos(entity->yaw); entity2->y += 2 * sin(entity->yaw); entity2->z -= 2; } else if ( entity->sprite == items[TOOL_CRYSTALSHARD].index ) { entity2 = spawnFlame(entity, SPRITE_CRYSTALFLAME); entity2->x += 2 * cos(entity->yaw); entity2->y += 2 * sin(entity->yaw); entity2->z -= 2; } else if ( entity->sprite == items[TOOL_LANTERN].index ) { entity->z += 2; entity2 = spawnFlame(entity, SPRITE_FLAME); entity2->x += 2 * cos(entity->yaw); entity2->y += 2 * sin(entity->yaw); entity2->z += 1; } if ( MONSTER_SHIELDYAW > PI / 32 ) { if ( entity->sprite != items[TOOL_TORCH].index && entity->sprite != items[TOOL_LANTERN].index && entity->sprite != items[TOOL_CRYSTALSHARD].index ) { // shield, so rotate a little. entity->roll += PI / 64; } else { entity->x += 0.25 * cos(my->yaw); entity->y += 0.25 * sin(my->yaw); entity->pitch += PI / 16; if ( entity2 ) { entity2->x += 0.75 * cos(shieldarm->yaw); entity2->y += 0.75 * sin(shieldarm->yaw); } } } break; // cloak case LIMB_HUMANOID_CLOAK: if ( multiplayer != CLIENT ) { if ( myStats->cloak == nullptr || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) //TODO: isInvisible()? { entity->flags[INVISIBLE] = true; } else { entity->flags[INVISIBLE] = false; entity->sprite = itemModel(myStats->cloak); } if ( multiplayer == SERVER ) { // update sprites for clients if ( entity->skill[10] != entity->sprite ) { entity->skill[10] = entity->sprite; serverUpdateEntityBodypart(my, bodypart); } if ( entity->skill[11] != entity->flags[INVISIBLE] ) { entity->skill[11] = entity->flags[INVISIBLE]; serverUpdateEntityBodypart(my, bodypart); } if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) ) { serverUpdateEntityBodypart(my, bodypart); } } } else { if ( entity->sprite <= 0 ) { entity->flags[INVISIBLE] = true; } } entity->x -= cos(my->yaw); entity->y -= sin(my->yaw); entity->yaw += PI / 2; break; // helm case LIMB_HUMANOID_HELMET: entity->focalx = limbs[HUMAN][9][0]; // 0 entity->focaly = limbs[HUMAN][9][1]; // 0 entity->focalz = limbs[HUMAN][9][2]; // -1.75 entity->pitch = my->pitch; entity->roll = 0; if ( multiplayer != CLIENT ) { entity->sprite = itemModel(myStats->helmet); if ( myStats->helmet == nullptr || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) //TODO: isInvisible()? { entity->flags[INVISIBLE] = true; } else { entity->flags[INVISIBLE] = false; } if ( multiplayer == SERVER ) { // update sprites for clients if ( entity->skill[10] != entity->sprite ) { entity->skill[10] = entity->sprite; serverUpdateEntityBodypart(my, bodypart); } if ( entity->skill[11] != entity->flags[INVISIBLE] ) { entity->skill[11] = entity->flags[INVISIBLE]; serverUpdateEntityBodypart(my, bodypart); } if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) ) { serverUpdateEntityBodypart(my, bodypart); } } } else { if ( entity->sprite <= 0 ) { entity->flags[INVISIBLE] = true; } } my->setHelmetLimbOffset(entity); break; // mask case LIMB_HUMANOID_MASK: entity->focalx = limbs[HUMAN][10][0]; // 0 entity->focaly = limbs[HUMAN][10][1]; // 0 entity->focalz = limbs[HUMAN][10][2]; // .5 entity->pitch = my->pitch; entity->roll = PI / 2; if ( multiplayer != CLIENT ) { if ( myStats->mask == nullptr || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) //TODO: isInvisible()? { entity->flags[INVISIBLE] = true; } else { entity->flags[INVISIBLE] = false; } if ( myStats->mask != nullptr ) { if ( myStats->mask->type == TOOL_GLASSES ) { entity->sprite = 165; // GlassesWorn.vox } else { entity->sprite = itemModel(myStats->mask); } } if ( multiplayer == SERVER ) { // update sprites for clients if ( entity->skill[10] != entity->sprite ) { entity->skill[10] = entity->sprite; serverUpdateEntityBodypart(my, bodypart); } if ( entity->skill[11] != entity->flags[INVISIBLE] ) { entity->skill[11] = entity->flags[INVISIBLE]; serverUpdateEntityBodypart(my, bodypart); } if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) ) { serverUpdateEntityBodypart(my, bodypart); } } } else { if ( entity->sprite <= 0 ) { entity->flags[INVISIBLE] = true; } } if ( entity->sprite != 165 ) { entity->focalx = limbs[HUMAN][10][0] + .35; // .35 entity->focaly = limbs[HUMAN][10][1] - 2; // -2 entity->focalz = limbs[HUMAN][10][2]; // .5 } else { entity->focalx = limbs[HUMAN][10][0] + .25; // .25 entity->focaly = limbs[HUMAN][10][1] - 2.25; // -2.25 entity->focalz = limbs[HUMAN][10][2]; // .5 } break; } } // rotate shield a bit node_t* shieldNode = list_Node(&my->children, LIMB_HUMANOID_SHIELD); if ( shieldNode ) { Entity* shieldEntity = (Entity*)shieldNode->element; if ( shieldEntity->sprite != items[TOOL_TORCH].index && shieldEntity->sprite != items[TOOL_LANTERN].index && shieldEntity->sprite != items[TOOL_CRYSTALSHARD].index ) { shieldEntity->yaw -= PI / 6; } } if ( MONSTER_ATTACK > 0 && MONSTER_ATTACK <= MONSTER_POSE_MAGIC_CAST3 ) { MONSTER_ATTACKTIME++; } else if ( MONSTER_ATTACK == 0 ) { MONSTER_ATTACKTIME = 0; } else { // do nothing, don't reset attacktime or increment it. } }
void minotaurMoveBodyparts(Entity* my, Stat* myStats, double dist) { node_t* node; Entity* entity = NULL; Entity* rightbody = NULL; Entity* head = NULL; Entity* chest = NULL; int bodypart; // set invisibility //TODO: isInvisible()? if ( multiplayer != CLIENT ) { if ( myStats->EFFECTS[EFF_INVISIBLE] == true ) { my->flags[INVISIBLE] = true; my->flags[BLOCKSIGHT] = false; bodypart = 0; for (node = my->children.first; node != NULL; node = node->next) { if ( bodypart < 2 ) { bodypart++; continue; } if ( bodypart >= 7 ) { break; } entity = (Entity*)node->element; if ( !entity->flags[INVISIBLE] ) { entity->flags[INVISIBLE] = true; serverUpdateEntityBodypart(my, bodypart); } bodypart++; } } else { my->flags[INVISIBLE] = false; my->flags[BLOCKSIGHT] = true; bodypart = 0; for (node = my->children.first; node != NULL; node = node->next) { if ( bodypart < 2 ) { bodypart++; continue; } if ( bodypart >= 7 ) { break; } entity = (Entity*)node->element; if ( entity->flags[INVISIBLE] ) { entity->flags[INVISIBLE] = false; serverUpdateEntityBodypart(my, bodypart); serverUpdateEntityFlag(my, INVISIBLE); } bodypart++; } } } //Move bodyparts for (bodypart = 0, node = my->children.first; node != NULL; node = node->next, bodypart++) { if ( bodypart < 2 ) { continue; } entity = (Entity*)node->element; entity->x = my->x; entity->y = my->y; entity->z = my->z; entity->yaw = my->yaw; if ( bodypart == 2 ) { head = entity; } else if ( bodypart == 3 ) { chest = entity; } if ( bodypart == 4 || bodypart == 7 ) { if ( bodypart == 4 ) { rightbody = (Entity*)node->next->element; } if ( dist > 0.1 ) { if ( !rightbody->skill[0] ) { entity->pitch -= dist * MINOTAURWALKSPEED; if ( entity->pitch < -PI / 4.0 ) { entity->pitch = -PI / 4.0; if (bodypart == 4 && dist > .4) { playSound(115, 128); } } } else { entity->pitch += dist * MINOTAURWALKSPEED; if ( entity->pitch > PI / 4.0 ) { entity->pitch = PI / 4.0; if (bodypart == 4 && dist > .4) { playSound(115, 128); } } } } else { if ( entity->pitch < 0 ) { entity->pitch += 1 / fmax(dist * .1, 10.0); if ( entity->pitch > 0 ) { entity->pitch = 0; } } else if ( entity->pitch > 0 ) { entity->pitch -= 1 / fmax(dist * .1, 10.0); if ( entity->pitch < 0 ) { entity->pitch = 0; } } } } else if ( bodypart == 5 || bodypart == 6 ) { if ( bodypart == 6 ) { if ( my->monsterAttack > 0 ) { // vertical chop windup if ( my->monsterAttack == MONSTER_POSE_MELEE_WINDUP1 ) { if ( my->monsterAttackTime == 0 ) { // init rotations entity->pitch = 0; my->monsterArmbended = 0; my->monsterWeaponYaw = 0; entity->roll = 0; entity->skill[1] = 0; } limbAnimateToLimit(entity, ANIMATE_PITCH, -0.25, 5 * PI / 4, false, 0.0); if ( my->monsterAttackTime >= ANIMATE_DURATION_WINDUP / (monsterGlobalAnimationMultiplier / 10.0) ) { if ( multiplayer != CLIENT ) { my->attack(1, 0, nullptr); } } } // ceiling buster chop windup if ( my->monsterAttack == MONSTER_POSE_MELEE_WINDUP2 ) { if ( my->monsterAttackTime == 0 ) { // init rotations entity->pitch = 0; my->monsterArmbended = 0; my->monsterWeaponYaw = 0; entity->roll = 0; entity->skill[1] = 0; } limbAnimateToLimit(entity, ANIMATE_PITCH, -0.25, 5 * PI / 4, false, 0.0); if ( my->monsterAttackTime >= ANIMATE_DURATION_WINDUP / (monsterGlobalAnimationMultiplier / 10.0) ) { my->monsterAttack = 1; } } // vertical chop attack else if ( my->monsterAttack == 1 ) { if ( entity->pitch >= 3 * PI / 2 ) { my->monsterArmbended = 1; } if ( entity->skill[1] == 0 ) { // chop forwards if ( limbAnimateToLimit(entity, ANIMATE_PITCH, 0.4, PI / 3, false, 0.0) ) { entity->skill[1] = 1; } } else if ( entity->skill[1] == 1 ) { // return to neutral if ( limbAnimateToLimit(entity, ANIMATE_PITCH, -0.25, 7 * PI / 4, false, 0.0) ) { entity->skill[0] = rightbody->skill[0]; my->monsterWeaponYaw = 0; entity->pitch = rightbody->pitch; entity->roll = 0; my->monsterArmbended = 0; my->monsterAttack = 0; } } } } } if ( bodypart != 6 || (MONSTER_ATTACK == 0 && MONSTER_ATTACKTIME == 0) ) { if ( dist > 0.1 ) { if ( entity->skill[0] ) { entity->pitch -= dist * MINOTAURWALKSPEED; if ( entity->pitch < -PI / 4.0 ) { entity->skill[0] = 0; entity->pitch = -PI / 4.0; } } else { entity->pitch += dist * MINOTAURWALKSPEED; if ( entity->pitch > PI / 4.0 ) { entity->skill[0] = 1; entity->pitch = PI / 4.0; } } } else { if ( entity->pitch < 0 ) { entity->pitch += 1 / fmax(dist * .1, 10.0); if ( entity->pitch > 0 ) { entity->pitch = 0; } } else if ( entity->pitch > 0 ) { entity->pitch -= 1 / fmax(dist * .1, 10.0); if ( entity->pitch < 0 ) { entity->pitch = 0; } } } } } if ( !MONSTER_ATTACK ) { if ( bodypart == 6 ) { entity->yaw += entity->pitch; head->yaw = entity->yaw; chest->yaw = entity->yaw; } else if ( bodypart == 7 ) { entity->yaw -= entity->pitch; } } switch ( bodypart ) { // head case 2: entity->z -= 11; break; // chest case 3: entity->z -= 4.5; break; // right leg case 4: entity->x += 2.5 * cos(my->yaw + PI / 2) - .5 * cos(my->yaw); entity->y += 2.5 * sin(my->yaw + PI / 2) - .5 * sin(my->yaw); entity->z += 2.5; break; // left leg case 5: entity->x -= 2.5 * cos(my->yaw + PI / 2) + .5 * cos(my->yaw); entity->y -= 2.5 * sin(my->yaw + PI / 2) + .5 * sin(my->yaw); entity->z += 2.5; break; // right arm case 6: entity->z -= 6; entity->yaw += MONSTER_WEAPONYAW; break; // left arm case 7: entity->z -= 6; break; } } if ( MONSTER_ATTACK != 0 ) { MONSTER_ATTACKTIME++; } else { MONSTER_ATTACKTIME = 0; } }
void shopkeeperMoveBodyparts(Entity *my, stat_t *myStats, double dist) { node_t *node; Entity *entity = NULL; Entity *rightbody = NULL; int bodypart; // set invisibility if( multiplayer != CLIENT ) { if( myStats->EFFECTS[EFF_INVISIBLE] == TRUE ) { my->flags[INVISIBLE] = TRUE; my->flags[BLOCKSIGHT] = FALSE; bodypart=0; for(node = my->children.first; node!=NULL; node=node->next) { if( bodypart<2 ) { bodypart++; continue; } if( bodypart>=7 ) { break; } entity = (Entity *)node->element; if( !entity->flags[INVISIBLE] ) { entity->flags[INVISIBLE] = TRUE; serverUpdateEntityBodypart(my,bodypart); } bodypart++; } } else { my->flags[INVISIBLE] = FALSE; my->flags[BLOCKSIGHT] = TRUE; bodypart=0; for(node = my->children.first; node!=NULL; node=node->next) { if( bodypart<2 ) { bodypart++; continue; } if( bodypart>=7 ) { break; } entity = (Entity *)node->element; if( entity->flags[INVISIBLE] ) { entity->flags[INVISIBLE] = FALSE; serverUpdateEntityBodypart(my,bodypart); } bodypart++; } } // sleeping if( myStats->EFFECTS[EFF_ASLEEP] ) { my->z = 1.5; my->pitch = PI/4; } else { my->z = -1; my->pitch = 0; } } //Move bodyparts for(bodypart=0, node = my->children.first; node!=NULL; node=node->next, bodypart++) { if( bodypart<2 ) { continue; } entity = (Entity *)node->element; entity->x = my->x; entity->y = my->y; entity->z = my->z; entity->yaw = my->yaw; if( bodypart==3||bodypart==6 ) { if( bodypart==3 ) rightbody = (Entity *)node->next->element; if( dist>0.1 && bodypart!=6 ) { if( !rightbody->skill[0] ) { entity->pitch -= dist*SHOPKEEPERWALKSPEED; if( entity->pitch < -PI/4.0 ) { entity->pitch = -PI/4.0; if(bodypart==3) { entity->skill[0]=1; if( dist>.4 ) playSoundEntityLocal(my,rand()%7,32); } } } else { entity->pitch += dist*SHOPKEEPERWALKSPEED; if( entity->pitch > PI/4.0 ) { entity->pitch = PI/4.0; if(bodypart==3) { entity->skill[0]=0; if( dist>.4 ) playSoundEntityLocal(my,rand()%7,32); } } } } else { if( entity->pitch < 0 ) { entity->pitch += 1/fmax(dist*.1,10.0); if( entity->pitch > 0 ) entity->pitch=0; } else if( entity->pitch > 0 ) { entity->pitch -= 1/fmax(dist*.1,10.0); if( entity->pitch < 0 ) entity->pitch=0; } } } else if( bodypart==4||bodypart==5 ) { if( bodypart==5 ) { if( MONSTER_ATTACK == 1 ) { // vertical chop if( MONSTER_ATTACKTIME == 0 ) { MONSTER_ARMBENDED = 0; MONSTER_WEAPONYAW = 0; entity->pitch = -3*PI/4; entity->roll = 0; } else { if( entity->pitch >= -PI/2 ) MONSTER_ARMBENDED = 1; if( entity->pitch >= PI/4 ) { entity->skill[0] = rightbody->skill[0]; MONSTER_WEAPONYAW = 0; entity->pitch = rightbody->pitch; entity->roll = 0; MONSTER_ARMBENDED = 0; MONSTER_ATTACK = 0; } else { entity->pitch += .25; } } } else if( MONSTER_ATTACK == 2 ) { // horizontal chop if( MONSTER_ATTACKTIME == 0 ) { MONSTER_ARMBENDED = 1; MONSTER_WEAPONYAW = -3*PI/4; entity->pitch = 0; entity->roll = -PI/2; } else { if( MONSTER_WEAPONYAW >= PI/8 ) { entity->skill[0] = rightbody->skill[0]; MONSTER_WEAPONYAW = 0; entity->pitch = rightbody->pitch; entity->roll = 0; MONSTER_ARMBENDED = 0; MONSTER_ATTACK = 0; } else { MONSTER_WEAPONYAW += .25; } } } else if( MONSTER_ATTACK == 3 ) { // stab if( MONSTER_ATTACKTIME == 0 ) { MONSTER_ARMBENDED = 0; MONSTER_WEAPONYAW = 0; entity->pitch = 2*PI/3; entity->roll = 0; } else { if( MONSTER_ATTACKTIME >= 5 ) { MONSTER_ARMBENDED = 1; entity->pitch = -PI/6; } if( MONSTER_ATTACKTIME >= 10 ) { entity->skill[0] = rightbody->skill[0]; MONSTER_WEAPONYAW = 0; entity->pitch = rightbody->pitch; entity->roll = 0; MONSTER_ARMBENDED = 0; MONSTER_ATTACK = 0; } } } } if( bodypart!=5 || (MONSTER_ATTACK==0 && MONSTER_ATTACKTIME==0) ) { if( dist>0.1 ) { if( entity->skill[0] ) { entity->pitch -= dist*SHOPKEEPERWALKSPEED; if( entity->pitch < -PI/4.0 ) { entity->skill[0]=0; entity->pitch = -PI/4.0; } } else { entity->pitch += dist*SHOPKEEPERWALKSPEED; if( entity->pitch > PI/4.0 ) { entity->skill[0]=1; entity->pitch = PI/4.0; } } } else { if( entity->pitch < 0 ) { entity->pitch += 1/fmax(dist*.1,10.0); if( entity->pitch > 0 ) entity->pitch=0; } else if( entity->pitch > 0 ) { entity->pitch -= 1/fmax(dist*.1,10.0); if( entity->pitch < 0 ) entity->pitch=0; } } } } switch( bodypart ) { // torso case 2: entity->x-=.25*cos(my->yaw); entity->y-=.25*sin(my->yaw); entity->z+=2.5; break; // right leg case 3: entity->x+=1*cos(my->yaw+PI/2)+.25*cos(my->yaw); entity->y+=1*sin(my->yaw+PI/2)+.25*sin(my->yaw); entity->z+=5; if( my->z >= 1.4 && my->z <= 1.6 ) { entity->yaw += PI/8; entity->pitch = -PI/2; } break; // left leg case 4: entity->x-=1*cos(my->yaw+PI/2)-.25*cos(my->yaw); entity->y-=1*sin(my->yaw+PI/2)-.25*sin(my->yaw); entity->z+=5; if( my->z >= 1.4 && my->z <= 1.6 ) { entity->yaw -= PI/8; entity->pitch = -PI/2; } break; // right arm case 5: entity->x+=2.25*cos(my->yaw+PI/2)-.20*cos(my->yaw); entity->y+=2.25*sin(my->yaw+PI/2)-.20*sin(my->yaw); entity->z+=1.5; entity->focalx = limbs[SHOPKEEPER][4][0]; // 0 entity->focaly = limbs[SHOPKEEPER][4][1]; // 0 entity->focalz = limbs[SHOPKEEPER][4][2]; // 1.5 entity->yaw += MONSTER_WEAPONYAW; if( my->z >= 1.4 && my->z <= 1.6 ) { entity->pitch = 0; } break; // left arm case 6: entity->x-=2.25*cos(my->yaw+PI/2)+.20*cos(my->yaw); entity->y-=2.25*sin(my->yaw+PI/2)+.20*sin(my->yaw); entity->z+=1.5; entity->focalx = limbs[SHOPKEEPER][5][0]; // 0 entity->focaly = limbs[SHOPKEEPER][5][1]; // 0 entity->focalz = limbs[SHOPKEEPER][5][2]; // 1.5 if( my->z >= 1.4 && my->z <= 1.6 ) { entity->pitch = 0; } break; } } if( MONSTER_ATTACK != 0 ) MONSTER_ATTACKTIME++; else MONSTER_ATTACKTIME=0; }