00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <engine/PhysicsParticleObject.h>
00022 #include <engine/ScorchedContext.h>
00023 #include <engine/ActionController.h>
00024 #include <landscapemap/LandscapeMaps.h>
00025 #include <target/TargetSpace.h>
00026 #include <target/TargetShield.h>
00027 #include <target/TargetLife.h>
00028 #include <tank/TankContainer.h>
00029 #include <tank/TankPosition.h>
00030 #include <weapons/Accessory.h>
00031 #include <weapons/Shield.h>
00032 #include <weapons/ShieldRoundReflective.h>
00033 #include <weapons/ShieldSquareReflective.h>
00034 #include <weapons/ShieldRoundMag.h>
00035 #include <actions/ShotBounce.h>
00036 #include <actions/ShotProjectile.h>
00037 #include <actions/ShieldHit.h>
00038 #include <common/Defines.h>
00039 #include <common/Logger.h>
00040 #include <common/OptionsTransient.h>
00041
00042 PhysicsParticleObject::PhysicsParticleObject() :
00043 handler_(0), context_(0), underGroundCollision_(false), iterations_(0),
00044 info_(ParticleTypeNone, 0, 0), rotateOnCollision_(false), wallCollision_(true)
00045 {
00046 }
00047
00048 PhysicsParticleObject::~PhysicsParticleObject()
00049 {
00050 }
00051
00052 void PhysicsParticleObject::applyForce(FixedVector &force)
00053 {
00054 velocity_ += force;
00055 }
00056
00057 void PhysicsParticleObject::setPhysics(
00058 PhysicsParticleInfo info,
00059 ScorchedContext &context,
00060 FixedVector &position, FixedVector &velocity,
00061 fixed sphereSize, fixed sphereDensity, fixed windFactor,
00062 bool underGroundCollision, bool rotateOnCollision, bool wallCollision)
00063 {
00064 info_ = info;
00065 context_ = &context;
00066 underGroundCollision_ = underGroundCollision;
00067 rotateOnCollision_ = rotateOnCollision;
00068 wallCollision_ = wallCollision;
00069
00070 FixedVector zaxis(0, 0, 1);
00071 rotation_.setQuatFromAxisAndAngle(zaxis, 0);
00072 position_ = position;
00073 velocity_ = velocity;
00074 windFactor_ =
00075 context_->getOptionsTransient().getWindDirection() *
00076 context_->getOptionsTransient().getWindSpeed() /
00077 fixed(true, 25000) * windFactor;
00078
00079 FixedVector gravity(0, 0, context_->getOptionsGame().getGravity());
00080 windFactor_ += gravity;
00081 windFactor_ /= 70;
00082 }
00083
00084 void PhysicsParticleObject::simulate(fixed frameTime)
00085 {
00086 iterations_++;
00087 velocity_ += windFactor_;
00088 position_ += velocity_ / 100;
00089
00090 if (rotateOnCollision_)
00091 {
00092 rotation_ += avelocity_;
00093 rotation_.Normalize();
00094 }
00095
00096 if (!handler_ || !context_) return;
00097
00098 checkCollision();
00099 }
00100
00101 void PhysicsParticleObject::checkCollision()
00102 {
00103 CollisionInfo collision;
00104 collision.collisionId = CollisionIdNone;
00105
00106 fixed bounceFactor = 2;
00107
00108
00109 CollisionAction action = CollisionActionNone;
00110 Target *target = context_->getTargetSpace().getCollision(position_);
00111 switch (info_.type_)
00112 {
00113 case ParticleTypeShot:
00114 if (getTargetCollision(collision, target) ||
00115 getShieldCollision(collision, target) ||
00116 getLandscapeCollision(collision) ||
00117 getRoofCollision(collision) ||
00118 getWallCollision(collision))
00119 {
00120 action = checkShotCollision(collision, target);
00121 if (action != CollisionActionNone)
00122 {
00123 if (context_->getOptionsGame().getActionSyncCheck())
00124 {
00125 context_->getActionController().addSyncCheck(
00126 S3D::formatStringBuffer("Shot Collision : %i %i %i,%i,%i",
00127 (int) action,
00128 (int) collision.collisionId,
00129 position_[0].getInternal(),
00130 position_[1].getInternal(),
00131 position_[2].getInternal()));
00132 }
00133 }
00134 }
00135 break;
00136 case ParticleTypeBounce:
00137 if (getTargetBounceCollision(collision, target) ||
00138 getTargetCollision(collision, target) ||
00139 getShieldCollision(collision, target) ||
00140 getLandscapeCollision(collision) ||
00141 getWallCollision(collision))
00142 {
00143 action = checkBounceCollision(collision, target);
00144
00145 velocity_[2] = MIN(velocity_[2], 1);
00146 bounceFactor = fixed(true, 1750);
00147 }
00148 break;
00149 case ParticleTypeFalling:
00150 if (getLandscapeCollision(collision) ||
00151 getWallCollision(collision))
00152 {
00153 action = checkFallingCollision(collision, target);
00154 }
00155 break;
00156 }
00157
00158
00159 switch (action)
00160 {
00161 case CollisionActionCollision:
00162 handler_->collision(*this, collision.collisionId);
00163 break;
00164 case CollisionActionBounce:
00165 {
00166
00167
00168 position_ -= velocity_ / 100;
00169
00170
00171 fixed strength = velocity_.Magnitude();
00172 FixedVector direction = velocity_ / strength;
00173 fixed dotp = -collision.normal.dotP(direction);
00174 direction = direction + collision.normal * (dotp * bounceFactor);
00175 velocity_ = direction * strength * collision.deflectFactor;
00176
00177 fixed landHeight =
00178 context_->getLandscapeMaps().getGroundMaps().
00179 getInterpHeight(position_[0], position_[1]);
00180 fixed particleHeight = position_[2] - landHeight;
00181 if (underGroundCollision_)
00182 {
00183 if (particleHeight > fixed(true, -1000))
00184 position_[2] = landHeight - fixed(true, 1000);
00185 }
00186 else
00187 {
00188 if (particleHeight < fixed(true, 1000))
00189 position_[2] = landHeight + fixed(true, 1000);
00190 }
00191
00192 if (rotateOnCollision_)
00193 {
00194 FixedVector up(0, 0, -1);
00195 FixedVector rotAxis = velocity_ * up;
00196 rotAxis.StoreNormalize();
00197 avelocity_.setQuatFromAxisAndAngle(rotAxis, velocity_.Magnitude() * 5);
00198 }
00199 }
00200 break;
00201 }
00202 }
00203
00204 PhysicsParticleObject::CollisionAction PhysicsParticleObject::checkShotCollision(
00205 CollisionInfo &collision, Target *target)
00206 {
00207 int arenaX = context_->getLandscapeMaps().getGroundMaps().getArenaX();
00208 int arenaY = context_->getLandscapeMaps().getGroundMaps().getArenaY();
00209 int arenaWidth = context_->getLandscapeMaps().getGroundMaps().getArenaWidth();
00210 int arenaHeight = context_->getLandscapeMaps().getGroundMaps().getArenaHeight();
00211
00212 switch(collision.collisionId)
00213 {
00214 case CollisionIdLandscape:
00215 case CollisionIdRoof:
00216 case CollisionIdTarget:
00217 return CollisionActionCollision;
00218 break;
00219 case CollisionIdShield:
00220 if (target && target->getShield().getCurrentShield())
00221 {
00222 shotShieldHit(target);
00223
00224 if (target->getShield().getCurrentShield())
00225 {
00226 Shield *shield = (Shield *) target->getShield().getCurrentShield()->getAction();
00227 switch (shield->getShieldType())
00228 {
00229 case Shield::ShieldTypeRoundNormal:
00230 case Shield::ShieldTypeSquareNormal:
00231 return CollisionActionCollision;
00232 case Shield::ShieldTypeRoundReflective:
00233 case Shield::ShieldTypeSquareReflective:
00234 return CollisionActionBounce;
00235 case Shield::ShieldTypeRoundMag:
00236 {
00237 ShieldRoundMag *magShield = (ShieldRoundMag *) shield;
00238 FixedVector force(0, 0, magShield->getDeflectPower() / 50);
00239 velocity_ += force;
00240 }
00241 return CollisionActionNone;
00242 }
00243 }
00244 }
00245 break;
00246 case CollisionIdWallLeft:
00247 case CollisionIdWallRight:
00248 case CollisionIdWallTop:
00249 case CollisionIdWallBottom:
00250
00251 switch(collision.collisionId)
00252 {
00253 case CollisionIdWallLeft:
00254 position_[0] = arenaX + 1;
00255 break;
00256 case CollisionIdWallRight:
00257 position_[0] = arenaX + arenaWidth - 1;
00258 break;
00259 case CollisionIdWallTop:
00260 position_[1] = arenaY + 1;
00261 break;
00262 case CollisionIdWallBottom:
00263 position_[1] = arenaY + arenaHeight - 1;
00264 break;
00265 }
00266
00267 shotWallHit(collision);
00268
00269 handler_->wallCollision(*this, collision.collisionId);
00270
00271 switch (context_->getOptionsTransient().getWallType())
00272 {
00273 case OptionsTransient::wallBouncy:
00274 return CollisionActionBounce;
00275 case OptionsTransient::wallWrapAround:
00276
00277 switch (collision.collisionId)
00278 {
00279 case CollisionIdWallLeft:
00280 position_[0] = arenaX + arenaWidth - 10;
00281 break;
00282 case CollisionIdWallRight:
00283 position_[0] = arenaX + 10;
00284 break;
00285 case CollisionIdWallTop:
00286 position_[1] = arenaY + arenaHeight - 10;
00287 break;
00288 case CollisionIdWallBottom:
00289 position_[1] = arenaX + 10;
00290 break;
00291 }
00292 return CollisionActionNone;
00293 case OptionsTransient::wallConcrete:
00294 return CollisionActionCollision;
00295 }
00296 break;
00297 }
00298 return CollisionActionNone;
00299 }
00300
00301 PhysicsParticleObject::CollisionAction PhysicsParticleObject::checkBounceCollision(
00302 CollisionInfo &collision, Target *target)
00303 {
00304 int arenaX = context_->getLandscapeMaps().getGroundMaps().getArenaX();
00305 int arenaY = context_->getLandscapeMaps().getGroundMaps().getArenaY();
00306 int arenaWidth = context_->getLandscapeMaps().getGroundMaps().getArenaWidth();
00307 int arenaHeight = context_->getLandscapeMaps().getGroundMaps().getArenaHeight();
00308
00309 switch(collision.collisionId)
00310 {
00311 case CollisionIdRoof:
00312 return CollisionActionNone;
00313 break;
00314 case CollisionIdLandscape:
00315 return CollisionActionBounce;
00316 case CollisionIdWallLeft:
00317 case CollisionIdWallRight:
00318 case CollisionIdWallTop:
00319 case CollisionIdWallBottom:
00320
00321 if (context_->getOptionsTransient().getWallType() == OptionsTransient::wallBouncy ||
00322 context_->getOptionsTransient().getWallType() == OptionsTransient::wallConcrete)
00323 {
00324 switch(collision.collisionId)
00325 {
00326 case CollisionIdWallLeft:
00327 position_[0] = arenaX + 1;
00328 break;
00329 case CollisionIdWallRight:
00330 position_[0] = arenaX + arenaWidth - 1;
00331 break;
00332 case CollisionIdWallTop:
00333 position_[1] = arenaY + 1;
00334 break;
00335 case CollisionIdWallBottom:
00336 position_[1] = arenaY + arenaHeight - 1;
00337 break;
00338 }
00339 }
00340
00341 switch (context_->getOptionsTransient().getWallType())
00342 {
00343 case OptionsTransient::wallBouncy:
00344 return CollisionActionBounce;
00345 case OptionsTransient::wallWrapAround:
00346 return CollisionActionNone;
00347 case OptionsTransient::wallConcrete:
00348 return CollisionActionCollision;
00349 }
00350 break;
00351 case CollisionIdShield:
00352 bounceShieldHit(target);
00353 return CollisionActionBounce;
00354 break;
00355 case CollisionIdTarget:
00356 return CollisionActionCollision;
00357 break;
00358 }
00359 return CollisionActionNone;
00360 }
00361
00362 PhysicsParticleObject::CollisionAction PhysicsParticleObject::checkFallingCollision(
00363 CollisionInfo &collision, Target *target)
00364 {
00365 int arenaX = context_->getLandscapeMaps().getGroundMaps().getArenaX();
00366 int arenaY = context_->getLandscapeMaps().getGroundMaps().getArenaY();
00367 int arenaWidth = context_->getLandscapeMaps().getGroundMaps().getArenaWidth();
00368 int arenaHeight = context_->getLandscapeMaps().getGroundMaps().getArenaHeight();
00369
00370 switch(collision.collisionId)
00371 {
00372 case CollisionIdTarget:
00373 case CollisionIdShield:
00374 return CollisionActionNone;
00375 break;
00376 case CollisionIdRoof:
00377 case CollisionIdWallLeft:
00378 case CollisionIdWallRight:
00379 case CollisionIdWallTop:
00380 case CollisionIdWallBottom:
00381 switch(collision.collisionId)
00382 {
00383 case CollisionIdWallLeft:
00384 position_[0] = arenaX + 1;
00385 break;
00386 case CollisionIdWallRight:
00387 position_[0] = arenaX + arenaWidth - 1;
00388 break;
00389 case CollisionIdWallTop:
00390 position_[1] = arenaY + 1;
00391 break;
00392 case CollisionIdWallBottom:
00393 position_[1] = arenaY + arenaHeight - 1;
00394 break;
00395 }
00396
00397 return CollisionActionBounce;
00398 break;
00399 case CollisionIdLandscape:
00400 return CollisionActionCollision;
00401 break;
00402 }
00403 return CollisionActionNone;
00404 }
00405
00406 bool PhysicsParticleObject::getLandscapeCollision(CollisionInfo &collision)
00407 {
00408
00409
00410 fixed landHeight =
00411 context_->getLandscapeMaps().getGroundMaps().
00412 getInterpHeight(position_[0], position_[1]);
00413 if (underGroundCollision_)
00414 {
00415 if (position_[2] <= 0)
00416 {
00417 collision.collisionId = CollisionIdLandscape;
00418 collision.deflectFactor = 1;
00419 collision.normal = FixedVector(0, 0, -1);
00420 return true;
00421 }
00422 if (position_[2] >= landHeight)
00423 {
00424 collision.collisionId = CollisionIdLandscape;
00425 collision.deflectFactor = 1;
00426 context_->getLandscapeMaps().getGroundMaps().
00427 getInterpNormal(position_[0], position_[1], collision.normal);
00428 collision.normal = -collision.normal;
00429 return true;
00430 }
00431 }
00432 else
00433 {
00434 if (position_[2] <= 0)
00435 {
00436 collision.collisionId = CollisionIdLandscape;
00437 collision.deflectFactor = 1;
00438 collision.normal = FixedVector(0, 0, 1);
00439 return true;
00440 }
00441 if (position_[2] <= landHeight)
00442 {
00443 collision.collisionId = CollisionIdLandscape;
00444 collision.deflectFactor = 1;
00445 context_->getLandscapeMaps().getGroundMaps().
00446 getInterpNormal(position_[0], position_[1], collision.normal);
00447 return true;
00448 }
00449 }
00450 return false;
00451 }
00452
00453 bool PhysicsParticleObject::getRoofCollision(CollisionInfo &collision)
00454 {
00455
00456 fixed maxHeight = context_->getLandscapeMaps().getRoofMaps().getInterpRoofHeight(
00457 position_[0], position_[1]);
00458 if (position_[2] >= maxHeight)
00459 {
00460 collision.collisionId = CollisionIdRoof;
00461 collision.deflectFactor = 1;
00462 collision.normal = FixedVector(0, 0, -1);
00463 return true;
00464 }
00465 return false;
00466 }
00467
00468 bool PhysicsParticleObject::getWallCollision(CollisionInfo &collision)
00469 {
00470
00471 if (context_->getOptionsTransient().getWallType() == OptionsTransient::wallNone)
00472 {
00473 return false;
00474 }
00475
00476
00477 if (!wallCollision_) return false;
00478
00479 int arenaX = context_->getLandscapeMaps().getGroundMaps().getArenaX();
00480 int arenaY = context_->getLandscapeMaps().getGroundMaps().getArenaY();
00481 int arenaWidth = context_->getLandscapeMaps().getGroundMaps().getArenaWidth();
00482 int arenaHeight = context_->getLandscapeMaps().getGroundMaps().getArenaHeight();
00483 if (position_[0] <= arenaX)
00484 {
00485 collision.collisionId = CollisionIdWallLeft;
00486 collision.deflectFactor = 1;
00487 collision.normal = FixedVector(1, 0, 0);
00488 return true;
00489 }
00490 else if (position_[0] >= arenaX + arenaWidth)
00491 {
00492 collision.collisionId = CollisionIdWallRight;
00493 collision.deflectFactor = 1;
00494 collision.normal = FixedVector(-1, 0, 0);
00495 return true;
00496 }
00497 else if (position_[1] <= arenaY)
00498 {
00499 collision.collisionId = CollisionIdWallTop;
00500 collision.deflectFactor = 1;
00501 collision.normal = FixedVector(0, 1, 0);
00502 return true;
00503 }
00504 else if (position_[1] >= arenaY + arenaHeight)
00505 {
00506 collision.collisionId = CollisionIdWallBottom;
00507 collision.deflectFactor = 1;
00508 collision.normal = FixedVector(0, -1, 0);
00509 return true;
00510 }
00511 return false;
00512 }
00513
00514 bool PhysicsParticleObject::getShieldCollision(CollisionInfo &collision, Target *target)
00515 {
00516 if (!target) return false;
00517
00518
00519 Accessory *shieldAcc = target->getShield().getCurrentShield();
00520 if (!shieldAcc) return false;
00521 Shield *shield = (Shield *) shieldAcc->getAction();
00522
00523
00524 if (target->getPlayerId() == info_.playerId_)
00525 {
00526 return false;
00527 }
00528
00529
00530
00531 Tank *shotTank = context_->getTankContainer().getTankById(info_.playerId_);
00532 if (shotTank)
00533 {
00534 FixedVector offset = shotTank->getPosition().getTankPosition() -
00535 target->getLife().getTargetPosition();
00536 if (shield->tankInShield(offset))
00537 {
00538
00539 return false;
00540 }
00541 }
00542
00543
00544 FixedVector direction = position_ - target->getLife().getTargetPosition();
00545 if (!shield->inShield(direction)) return false;
00546
00547
00548 switch (shield->getShieldType())
00549 {
00550 case Shield::ShieldTypeRoundMag:
00551 collision.collisionId = CollisionIdShield;
00552 collision.deflectFactor = 1;
00553 collision.normal = FixedVector(0, 0, 1);
00554 return true;
00555 case Shield::ShieldTypeRoundNormal:
00556 case Shield::ShieldTypeRoundReflective:
00557 {
00558
00559 fixed deflectFactor = 1;
00560 if (shield->getShieldType() == Shield::ShieldTypeRoundReflective)
00561 {
00562 ShieldRoundReflective *squareRoundReflective =
00563 (ShieldRoundReflective *) shield;
00564 deflectFactor = squareRoundReflective->getDeflectFactor();
00565 }
00566
00567 collision.collisionId = CollisionIdShield;
00568 collision.deflectFactor = deflectFactor;
00569 collision.normal = (position_ - target->getLife().getTargetPosition()).Normalize();
00570 }
00571 return true;
00572 case Shield::ShieldTypeSquareReflective:
00573 case Shield::ShieldTypeSquareNormal:
00574 {
00575
00576 fixed deflectFactor = 1;
00577 if (shield->getShieldType() == Shield::ShieldTypeSquareReflective)
00578 {
00579 ShieldSquareReflective *squareSquareReflective =
00580 (ShieldSquareReflective *) shield;
00581 deflectFactor = squareSquareReflective->getDeflectFactor();
00582 }
00583
00584
00585 ShieldSquare *squareShield = (ShieldSquare *) shield;
00586 FixedVector &size = squareShield->getSize();
00587
00588 fixed diff0 = size[0] - (direction[0].abs());
00589 fixed diff1 = size[1] - (direction[1].abs());
00590 fixed diff2 = size[2] - (direction[2].abs());
00591 if (diff0 <= diff1 && diff0 <= diff2)
00592 {
00593 if (direction[0] > 0) collision.normal = FixedVector(-1, 0, 0);
00594 else collision.normal = FixedVector(1, 0, 0);
00595 }
00596 if (diff1 <= diff0 && diff1 <= diff2)
00597 {
00598 if (direction[1] > 0) collision.normal = FixedVector(0, -1, 0);
00599 else collision.normal = FixedVector(0, 1, 0);
00600 }
00601 if (diff2 <= diff0 && diff2 <= diff1)
00602 {
00603 if (direction[2] > 0) collision.normal = FixedVector(0, 0, -1);
00604 else collision.normal = FixedVector(0, 0, 1);
00605 }
00606
00607 collision.collisionId = CollisionIdShield;
00608 collision.deflectFactor = deflectFactor;
00609 }
00610 return true;
00611 }
00612
00613 return false;
00614 }
00615
00616 bool PhysicsParticleObject::getTargetCollision(CollisionInfo &collision, Target *target)
00617 {
00618 if (!target) return false;
00619
00620
00621 if (target->getPlayerId() == info_.playerId_) return false;
00622
00623
00624 if (target->getLife().collision(position_))
00625 {
00626 collision.normal = (position_ - target->getLife().getCenterPosition()).Normalize();
00627 collision.deflectFactor = 1;
00628 collision.collisionId = CollisionIdTarget;
00629 return true;
00630 }
00631
00632 return false;
00633 }
00634
00635 bool PhysicsParticleObject::getTargetBounceCollision(CollisionInfo &collision, Target *target)
00636 {
00637 if (info_.type_ != ParticleTypeBounce) return false;
00638
00639
00640
00641 std::map<unsigned int, Target *> collisionTargets;
00642 context_->getTargetSpace().getCollisionSet(position_, 1, collisionTargets, false);
00643 std::map<unsigned int, Target *>::iterator itor;
00644 for (itor = collisionTargets.begin();
00645 itor != collisionTargets.end();
00646 itor++)
00647 {
00648 Target *target = (*itor).second;
00649 if (target->getLife().collision(position_) ||
00650 target->getLife().collisionDistance(position_) < 1)
00651 {
00652 collision.normal = (position_ - target->getLife().getCenterPosition()).Normalize();
00653 collision.deflectFactor = 1;
00654 collision.collisionId = CollisionIdTarget;
00655 return true;
00656 }
00657 }
00658
00659 return false;
00660 }
00661
00662 void PhysicsParticleObject::shotShieldHit(Target *target)
00663 {
00664 }
00665
00666 void PhysicsParticleObject::bounceShieldHit(Target *target)
00667 {
00668 }
00669
00670 void PhysicsParticleObject::shotWallHit(CollisionInfo &collision)
00671 {
00672 }
00673
00674 PhysicsParticleActionObject::PhysicsParticleActionObject()
00675 {
00676 }
00677
00678 PhysicsParticleActionObject::~PhysicsParticleActionObject()
00679 {
00680 }
00681
00682 void PhysicsParticleActionObject::shotShieldHit(Target *target)
00683 {
00684 Shield *shield = (Shield *) target->getShield().getCurrentShield()->getAction();
00685 ShotProjectile *shot = (ShotProjectile *) info_.data_;
00686 fixed hurtFactor = shot->getWeapon()->getShieldHurtFactor(*context_);
00687 if (hurtFactor > 0)
00688 {
00689 if (shield->getShieldType() != Shield::ShieldTypeRoundMag)
00690 {
00691 context_->getActionController().addAction(
00692 new ShieldHit(target->getPlayerId(),
00693 position_,
00694 hurtFactor));
00695 }
00696 else
00697 {
00698 target->getShield().setShieldPower(
00699 target->getShield().getShieldPower() -
00700 shield->getHitRemovePower() * hurtFactor);
00701 }
00702 }
00703 }
00704
00705 void PhysicsParticleActionObject::bounceShieldHit(Target *target)
00706 {
00707 Shield *shield = (Shield *) target->getShield().getCurrentShield()->getAction();
00708 ShotBounce *shot = (ShotBounce *) info_.data_;
00709 fixed hurtFactor = shot->getWeapon()->getShieldHurtFactor(*context_);
00710 if (shield->getShieldType() != Shield::ShieldTypeRoundMag && hurtFactor > 0)
00711 {
00712 context_->getActionController().addAction(
00713 new ShieldHit(target->getPlayerId(),
00714 position_,
00715 hurtFactor));
00716 }
00717 }
00718
00719 #ifndef S3D_SERVER
00720
00721 #include <client/ScorchedClient.h>
00722 #include <graph/ParticleEmitter.h>
00723
00724 static void addWallCollisionParticle(Vector &position, ScorchedCollisionId collisionId)
00725 {
00726 Vector color(1.0f, 1.0f, 1.0f);
00727 ParticleEmitter emitter;
00728 emitter.setAttributes(
00729 8.5f, 8.0f,
00730 0.2f, 0.5f,
00731 0.01f, 0.02f,
00732 Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 0.0f, 0.0f),
00733 color, 1.0f,
00734 color, 1.0f,
00735 color, 0.0f,
00736 color, 0.0f,
00737 2.0f, 2.0f, 2.0f, 2.0f,
00738 2.0f, 2.0f, 2.0f, 2.0f,
00739 Vector(0.0f, 0.0f, 0.0f),
00740 false,
00741 false);
00742
00743 switch (collisionId)
00744 {
00745 case CollisionIdWallLeft:
00746 emitter.emitWallHit(position,
00747 ScorchedClient::instance()->getParticleEngine(),
00748 OptionsTransient::LeftSide);
00749 break;
00750 case CollisionIdWallRight:
00751 emitter.emitWallHit(position,
00752 ScorchedClient::instance()->getParticleEngine(),
00753 OptionsTransient::RightSide);
00754 break;
00755 case CollisionIdWallTop:
00756 emitter.emitWallHit(position,
00757 ScorchedClient::instance()->getParticleEngine(),
00758 OptionsTransient::TopSide);
00759 break;
00760 case CollisionIdWallBottom:
00761 emitter.emitWallHit(position,
00762 ScorchedClient::instance()->getParticleEngine(),
00763 OptionsTransient::BotSide);
00764 break;
00765 }
00766 }
00767 #endif
00768
00769 void PhysicsParticleActionObject::shotWallHit(CollisionInfo &collision)
00770 {
00771 #ifndef S3D_SERVER
00772 addWallCollisionParticle(position_.asVector(), collision.collisionId);
00773 #endif
00774 }