EarthlingCruiserMk3Beam::EarthlingCruiserMk3Beam(SpaceLocation *creator, Vector2 rpos, double lrange, double ldamage, double sdamage, int lfcount, SpaceObject *tgt) : SpaceLine(creator, creator->normal_pos(), 0, lrange, 0), frame(0), frame_count(lfcount), lpos(creator), rel_pos(rpos), damage_shots(sdamage) { STACKTRACE; set_depth(DEPTH_EXPLOSIONS); target = tgt; base_length = length; rel_pos.x *= -1; pos = normalize(pos + rotate(rel_pos, -PI/2+lpos->get_angle())); vel = lpos->get_vel(); id |= SPACE_LASER; damage_factor = ldamage; angle = trajectory_angle(target); if (!target->canCollide(this) || !canCollide(target)) state = 0; if (!(lpos && lpos->exists())) { lpos = 0; state = 0; } color = tw_makecol(100+tw_random()%105,100+tw_random()%105,255); got_spark = false; switch_counter = 0; }
void SlimePetEntity::readCollidingEntity(CollidingSpriteEntity* entity) { if (canCollide() && collideWithEntity(entity)) { if (entity->getType() >= ENTITY_ENEMY && entity->getType() <= ENTITY_ENEMY_MAX_COUNT) { EnemyEntity* enemyEntity = static_cast<EnemyEntity*>(entity); if (enemyEntity->canCollide()) { if (attackDelay <= 0.0f) { enemyEntity->hurt(getHurtParams(12, ShotTypeStandard,0, false, SourceTypeMelee, EnemyTypeNone,false)); attackDelay = 0.65f; float xs = (x + enemyEntity->getX()) / 2; float ys = (y + enemyEntity->getY()) / 2; SpriteEntity* star = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_HURT_IMPACT), xs, ys); star->setFading(true); star->setZ(y+ 100); star->setLifetime(0.7f); star->setType(ENTITY_EFFECT); star->setSpin(400.0f); } if (enemyEntity->getMovingStyle() == movWalking) { Vector2D vel = Vector2D(enemyEntity->getX(), enemyEntity->getY()).vectorTo(Vector2D(x, y), 100.0f ); giveRecoil(false, vel, 0.3f); } } } } }
void LassoLaser::collide(SpaceObject *o) { double old_length = length; double old_oldlen; int collison = FALSE; if((!canCollide(o)) || (!o->canCollide(this))) return; for (int i=0; i < BCC ; i++) { old_oldlen = o->collide_ray(Vector2(oldnx[i], oldny[i]), Vector2(oldnx[i] + oldex[i], oldny[i] + oldey[i]), oldlen[i]); collison = (collison || (old_oldlen != oldlen[i])); } length = o->collide_ray(normal_pos(), normal_pos() + edge(), length); if ( (length == old_length) && (!collison) ) return; play_sound2(LeftMissile->data->sampleExtra[0]); if ((LeftMissile->exists()) && (LeftMissile->sameShip(this)) && (!snapped)) LeftMissile->changeDirection(normalize(LeftMissile->get_angle()+PI/2,PI2)); if ((RightMissile->exists()) && (RightMissile->sameShip(this)) && (!snapped)) RightMissile->changeDirection(normalize(RightMissile->get_angle()-PI/2,PI2)); state = 0; snapped = TRUE; }
void EarthlingCruiserMk3Beam::calculate() { STACKTRACE; if (!(lpos && lpos->exists())) { lpos = 0; state = 0; } if ((frame < frame_count) && (lpos && lpos->exists())) { pos = lpos->normal_pos() + rotate(rel_pos, lpos->get_angle() - PI/2); vel = lpos->get_vel(); SpaceLine::calculate(); frame += frame_time; } else state = 0; if ((!target) && (switch_counter <= 0)) { SpaceObject *o; double rng = 1e40; SpaceObject *tgt = NULL; Query a; for (a.begin(this, bit(LAYER_SHIPS) + bit(LAYER_SHOTS) + bit(LAYER_SPECIAL) + bit(LAYER_CBODIES), base_length); a.current; a.next()) { o = a.currento; if (!o->isInvisible() && !o->sameTeam(this) && (o->collide_flag_anyone&bit(LAYER_LINES)) && (distance(o) < rng)) { tgt = o; rng = distance(o); } } if (tgt) { target = tgt; // switch_counter = 55; got_spark = false; } } if (target && (distance(target) <= base_length)) { length = base_length; if (target->exists() && canCollide(target) && target->canCollide(this)) { angle = trajectory_angle(target); } if (!target->exists()) target = NULL; } else { target = NULL; if (switch_counter <= 0) // die(); length = 0; else switch_counter -= frame_time; } color = tw_makecol(100+tw_random()%105,100+tw_random()%105,255); }
void BasiliskAimline::collide(SpaceObject *o) { STACKTRACE; if ((!canCollide(o)) || (!o->canCollide(this))) return; if (target == NULL && o->isShip()) target = o; return; }
bool Rectangle::collision(std::vector<Object*> objects){ if(canCollide()){ for(int i=0; i<objects.size(); i++){ if(objects[i] != this){ if(objects[i]->canCollide()){ if(collis(objects[i])){ setCollided(true); objects[i]->setCollided(true); return true; } } } } setCollided(false); } return false; }
// an exact copy, with a small modification: it also return a boolean value int ShipPart::collide_SpaceObject(SpaceObject *other) { STACKTRACE; // double dx, dy; // double dvx, dvy; double tmp; // int x1, y1; // int x2, y2; if (this == other) {tw_error("SpaceObject::collide - self!");} if ((!canCollide(other)) || (!other->canCollide(this))) return 0; if (!exists() || !other->exists()) return 0; pos = normal_pos(); Vector2 p1, p2, dp, dv; p1 = pos; p2 = other->normal_pos(); dp.x = min_delta(p1.x, p2.x, map_size.x); dp.y = min_delta(p1.y, p2.y, map_size.y); p2 = p1 - dp - other->size / 2; p1 = p1 - size / 2; /* x1 = (int)(normal_x() - (w / 2.0)); y1 = (int)(normal_y() - (h / 2.0)); dx = min_delta(normal_x(), other->normal_x(), map_size.x); dy = min_delta(normal_y(), other->normal_y(), Y_MAX); x2 = (int)(normal_x() - dx - ((other->w) / 2.0)); y2 = (int)(normal_y() - dy - ((other->h) / 2.0));*/ if (!sprite->collide(iround(p1.x), iround(p1.y), sprite_index, iround(p2.x), iround(p2.y), other->get_sprite_index(), other->get_sprite() )) return 0; //sprite->collide(x1, y1, sprite_index, x2, y2, other->sprite_index, other->sprite); inflict_damage(other); other->inflict_damage(this); if (!mass || !other->mass) return 0; dv = vel - other->vel; p1 = pos; p2 = other->normal_pos(); dp.x = min_delta(p1.x, p2.x, map_size.x); dp.y = min_delta(p1.y, p2.y, map_size.y); p2 = p1 - dp - other->size / 2; p1 = p1 - size / 2; /*x1 = (int)(normal_x() - (w / 2.0)); y1 = (int)(normal_y() - (h / 2.0)); dx = min_delta(normal_x(), other->normal_x(), map_size.x); dy = min_delta(normal_y(), other->normal_y(), Y_MAX); x2 = (int)(normal_x() - dx - ((other->w) / 2.0)); y2 = (int)(normal_y() - dy - ((other->h) / 2.0));*/ while ((dp.x == 0) && (dp.y == 0)) { dp.x = (tw_random(5) - 2) / 99.0; dp.y = (tw_random(5) - 2) / 99.0; } Vector2 _dp = unit_vector(dp); tmp = dot_product(dv, _dp); tmp = ( -2 * tmp ); if (mass + other->mass > 1) tmp = tmp * (mass * other->mass) / (mass + other->mass); if (tmp >= 0) { if (mass > 1) vel += _dp * tmp / mass; if (other->mass > 1) other->change_vel (- _dp * tmp / other->mass ); } Vector2 nd; nd = unit_vector(dp); if (mass + other->mass > 1) nd /= (mass + other->mass); while (sprite->collide(iround(p1.x), iround(p1.y), sprite_index, iround(p2.x), iround(p2.y), other->get_sprite_index(), other->get_sprite() )) { pos = normalize(pos + nd * other->mass); other->pos = normalize(other->pos - nd * mass); p1 = pos; p2 = other->normal_pos(); dp.x = min_delta(p1.x, p2.x, map_size.x); dp.y = min_delta(p1.y, p2.y, map_size.y); p2 = p1 - dp - other->size / 2; p1 = p1 - size / 2; } #ifdef _DEBUG SpaceObject *c1 = this; SpaceObject *c2 = other; if (fabs(c1->vel.x) > 1E6 || fabs(c1->vel.y) > 1E6 || fabs(c2->vel.x) > 1E6 || fabs(c2->vel.y) > 1E6 ) { int a1 = c1->canCollide(c2); int a2 = c2->canCollide(c1); bool b = ((c1->canCollide(c2) & c2->canCollide(c1)) == 0 ); tw_error("velocity error in collision involving objects [%s] and [%s]", c1->get_identity(), c2->get_identity()); } #endif return 1; }
// an exact copy, with a small modification: it also return a boolean value int ShipPart2::collide_SpaceObject(SpaceObject *other) { STACKTRACE; // double dx, dy; // double dvx, dvy; double tmp; // int x1, y1; // int x2, y2; if (this == other) { tw_error("SpaceObject::collide - self!"); } if ((!canCollide(other)) || (!other->canCollide(this))) return 0; if (!exists() || !other->exists()) return 0; pos = normal_pos(); Vector2 p1, p2, dp, dv; p1 = pos; p2 = other->normal_pos(); dp.x = min_delta(p1.x, p2.x, map_size.x); dp.y = min_delta(p1.y, p2.y, map_size.y); p2 = p1 - dp - other->size / 2; p1 = p1 - size / 2; /* x1 = (int)(normal_x() - (w / 2.0)); y1 = (int)(normal_y() - (h / 2.0)); dx = min_delta(normal_x(), other->normal_x(), map_size.x); dy = min_delta(normal_y(), other->normal_y(), Y_MAX); x2 = (int)(normal_x() - dx - ((other->w) / 2.0)); y2 = (int)(normal_y() - dy - ((other->h) / 2.0));*/ if (!sprite->collide(iround(p1.x), iround(p1.y), sprite_index, iround(p2.x), iround(p2.y), other->get_sprite_index(), other->get_sprite() )) return 0; //sprite->collide(x1, y1, sprite_index, x2, y2, other->sprite_index, other->sprite); inflict_damage(other); other->inflict_damage(this); if (!mass || !other->mass) return 0; dv = vel - other->vel; p1 = pos; p2 = other->normal_pos(); dp.x = min_delta(p1.x, p2.x, map_size.x); dp.y = min_delta(p1.y, p2.y, map_size.y); p2 = p1 - dp - other->size / 2; p1 = p1 - size / 2; /*x1 = (int)(normal_x() - (w / 2.0)); y1 = (int)(normal_y() - (h / 2.0)); dx = min_delta(normal_x(), other->normal_x(), map_size.x); dy = min_delta(normal_y(), other->normal_y(), Y_MAX); x2 = (int)(normal_x() - dx - ((other->w) / 2.0)); y2 = (int)(normal_y() - dy - ((other->h) / 2.0));*/ while ((dp.x == 0) && (dp.y == 0)) { dp.x = (tw_random(5) - 2) / 99.0; dp.y = (tw_random(5) - 2) / 99.0; } Vector2 _dp = unit_vector(dp); tmp = dot_product(dv, _dp); tmp = ( -2 * tmp ); tmp = tmp * (mass * other->mass) / (mass + other->mass); if (tmp >= 0) { vel += _dp * tmp / mass; other->vel -= _dp * tmp / other->mass; } Vector2 nd; nd = unit_vector(dp); nd /= (mass + other->mass); while (sprite->collide(iround(p1.x), iround(p1.y), sprite_index, iround(p2.x), iround(p2.y), other->get_sprite_index(), other->get_sprite() )) { pos = normalize(pos + nd * other->mass); other->pos = normalize(other->pos - nd * mass); p1 = pos; p2 = other->normal_pos(); dp.x = min_delta(p1.x, p2.x, map_size.x); dp.y = min_delta(p1.y, p2.y, map_size.y); p2 = p1 - dp - other->size / 2; p1 = p1 - size / 2; } return 1; }
void SlimePetEntity::animate(float delay) { if (age < 0.0f) { age += delay; } else { attackDelay -= delay; if (isJumping) { hVelocity -= 700.0f * delay; h += hVelocity * delay; bool firstTimeGround = false; if (h <= 0.0f) { h = 0.0f; if (isFalling()) { fall(); } else { if (isFirstJumping) { isFirstJumping = false; firstTimeGround = true; hVelocity = 160.0f; SoundManager::getInstance().playSound(SOUND_SLIME_IMAPCT); } else { jumpingDelay = 0.3f + 0.1f * (rand() % 15); isJumping = false; SoundManager::getInstance().playSound(SOUND_SLIME_IMAPCT_WEAK); } } } if (firstTimeGround) frame = 0; else if (hVelocity > -190.0f) frame = 2; else frame = 1; } else if (isFalling()) { fall(); } else { jumpingDelay -= delay; if (jumpingDelay < 0.0f) { SoundManager::getInstance().playSound(SOUND_SLIME_JUMP); hVelocity = 300.0f + rand() % 250; isJumping = true; isFirstJumping = true; float randVel = 250.0f + rand() % 250; setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(), randVel )); } else if (jumpingDelay < 0.1f) frame = 1; else frame = 0; } BaseCreatureEntity::animate(delay); if (canCollide()) testSpriteCollisions(); } z = y + 14; }
void CyclopsEntity::animate(float delay) { if (age <= 0.0f) { age += delay; return; } if (isAgonising) { if (h < -0.01f) { isDying = true; game().addCorpse(x, y, deathFrame); if (dyingSound != SOUND_NONE) SoundManager::getInstance().playSound(dyingSound); } else { frame = dyingFrame; hVelocity -= 700.0f * delay; h += hVelocity * delay; } return; } // special states if (specialState[SpecialStateIce].active) delay *= specialState[SpecialStateIce].param1; // IA computeStates(delay); // collisions if (canCollide()) testSpriteCollisions(); BaseCreatureEntity::animate(delay); // old frame (for sound) int oldFrame = frame; // current frame if (state == 0) { int r = ((int)(age * 5.0f)) % 4; if (r == 2) frame = 0; else if (r == 3) frame = 2; else frame = r; if (oldFrame == 1 && frame == 0) SoundManager::getInstance().playSound(SOUND_HEAVY_STEP_00); else if (oldFrame == 2 && frame == 0) SoundManager::getInstance().playSound(SOUND_HEAVY_STEP_01); } else if (state == 1) { isMirroring = game().getPlayer()->getX() > x; frame = timer > 0.5f ? 4 : 3; } else if (state == 2) { frame = 4; } else if (state == 3) { frame = 6; } else if (state == 4) { frame = 7; } // frame's mirroring if (velocity.x > 1.0f) isMirroring = true; else if (velocity.x < -1.0f) isMirroring = false; z = y + 36; }
bool Entity::isSolid() { if ( physics == nullptr ) return false; return physics->isSolid() && canCollide(); }
/** * Load this object from a template * @param objTemplate template to load from * @return true if success */ bool SceneObject::LoadFromTemplate( ObjectTemplatePtr objTemplate, const SimEntityData& data ) { if( !objTemplate ) return false; Assert( objTemplate->mpSimFactory ); // cast to object template to the type we expect mSceneObjectTemplate = static_pointer_cast< SceneObjectTemplate, ObjectTemplate>( objTemplate ); IrrFactory& irrFactory = mSceneObjectTemplate->mpSimFactory->getIrrFactory(); // are we an animated mesh? if( mSceneObjectTemplate->mAniMesh ) { mAniSceneNode = irrFactory.addAnimatedMeshSceneNode( mSceneObjectTemplate->mAniMesh.get() ); if (mSceneObjectTemplate->mCastsShadow) { mAniSceneNode->addShadowVolumeSceneNode(); } mFPSCamera = mSceneObjectTemplate->mFPSCamera; // reminder to attach camera later mAniSceneNode->setAnimationSpeed(0); mStartFrame = mAniSceneNode->getStartFrame(); mEndFrame = mAniSceneNode->getEndFrame(); mAniSceneNode->setFrameLoop(0,0); mAniSceneNode->setCurrentFrame(0); mSceneNode = mAniSceneNode; } // are we a terrain? else if( mSceneObjectTemplate->mHeightmap != "" ) { mTerrSceneNode = irrFactory.addTerrainSceneNode( mSceneObjectTemplate->mHeightmap.c_str() ); mSceneNode = mTerrSceneNode; mTerrSceneNode->scaleTexture( mSceneObjectTemplate->mScaleTexture.X, mSceneObjectTemplate->mScaleTexture.Y ); } // are we a particle system? else if( mSceneObjectTemplate->mParticleSystem != "" ) { mParticleSystemNode = irrFactory.addParticleSystemNode( mSceneObjectTemplate->mParticleSystem ); mSceneNode = mParticleSystemNode; // don't add a triangle selector for a particle node } if( mSceneNode ) { // assign the textures for( uint32_t i = 0; i < (uint32_t)mSceneObjectTemplate->mTextures.size(); ++i ) mSceneNode->setMaterialTexture( i, mSceneObjectTemplate->mTextures[i].get() ); // set the material flags std::vector<IrrMaterialFlag>::const_iterator flagItr = mSceneObjectTemplate->mMaterialFlags.begin(); std::vector<IrrMaterialFlag>::const_iterator flagEnd = mSceneObjectTemplate->mMaterialFlags.end(); for( ; flagItr != flagEnd; ++flagItr ) mSceneNode->setMaterialFlag( flagItr->mFlag, flagItr->mValue ); // set the material type mSceneNode->setMaterialType( mSceneObjectTemplate->mMaterialType ); // set the node scale Vector3f scale = mSceneObjectTemplate->mScale; /// we can optionally multiply by a custom scale scale.X = scale.X * data.GetScale().X; scale.Y = scale.Y * data.GetScale().Y; scale.Z = scale.Z * data.GetScale().Z; mSceneNode->setScale( ConvertNeroToIrrlichtPosition(scale) ); // make the id of the scene node the same as the SimId of our object mSceneNode->setID(ConvertSimIdToSceneId(data.GetId(), data.GetType())); // set the position of the object SetPosition( data.GetPosition() ); // set the rotation of the object SetRotation( data.GetRotation() ); // set up the triangle selector for this object //if (data.GetType() > 0) { { ITriangleSelector_IPtr tri_selector = GetTriangleSelector(); if (!tri_selector) { LOG_F_WARNING("collision", "could not create triangle selector for collisions with object " << GetId()); } } //} // additionally, add a collision response animator if (canCollide()) { // the world will return the triangles that match the type mask ITriangleSelector* world = new CollideByTypeTriangleSelector(mSceneObjectTemplate->mCollisionMask); // get the axis-aligned bounding box for the node BBoxf box = mSceneNode->getBoundingBox(); // use the aabbox to make the ellipsoid for the collision response animator Vector3f ellipsoid_radius = box.MaxEdge - box.getCenter(); // TODO: might add gravity here Vector3f gravity(0,0,0); // ellipsoid translation relative to object coordinates Vector3f ellipsoid_translation(0,0,0); mCollider = GetSceneManager()->createCollisionResponseAnimator( world, mSceneNode.get(), ellipsoid_radius, gravity, ellipsoid_translation); if (!mCollider) { LOG_F_ERROR("collision", "could not create Collision Response Animator for object id: " << data.GetId()); } else { SafeIrrDrop(world); // we don't need the handle mSceneNode->addAnimator(mCollider.get()); LOG_F_DEBUG("collision", "added collision response animator for object id: " << data.GetId() << " of type: " << data.GetType() << " for collision with mask: " << mSceneObjectTemplate->mCollisionMask << " with bounding ellipsoid: " << ellipsoid_radius); } } #if SCENEOBJECT_ENABLE_STATS // debug information if( mTerrSceneNode ) { const aabbox3df& bbox = mTerrSceneNode->getBoundingBox(); vector3df dim = bbox.MaxEdge - bbox.MinEdge; float32_t vol = dim.X * dim.Y * dim.Z; vol = (vol<0) ? -vol : vol; LOG_F_MSG( "render", "Added terrain with heightmap: " << mSceneObjectTemplate->mHeightmap ); LOG_F_MSG( "render", " Dim: (" << dim.X << ", " << dim.Y << ", " << dim.Z << ")" ); LOG_F_MSG( "render", " Volume: " << vol ); } #endif // end SCENEOBJECT_ENABLE_STATS } return true; }