* Handles explosions. * * HE, smoke and fire explodes in a circular pattern on 1 level only. HE however damages floor tiles of the above level. Not the units on it. * HE destroys an object if its armor is lower than the explosive power, then it's HE blockage is applied for further propagation. * See http://www.ufopaedia.org/index.php?title=Explosions for more info. * @param center Center of t
| 1103 | * @param unit The unit that caused the explosion. |
| 1104 | */ |
| 1105 | void TileEngine::explode(const Position ¢er, int power, ItemDamageType type, int maxRadius, BattleUnit *unit) |
| 1106 | { |
| 1107 | double centerZ = center.z / 24 + 0.5; |
| 1108 | double centerX = center.x / 16 + 0.5; |
| 1109 | double centerY = center.y / 16 + 0.5; |
| 1110 | int power_, penetration; |
| 1111 | std::set<Tile*> tilesAffected; |
| 1112 | std::pair<std::set<Tile*>::iterator,bool> ret; |
| 1113 | |
| 1114 | if (type == DT_IN) |
| 1115 | { |
| 1116 | power /= 2; |
| 1117 | } |
| 1118 | |
| 1119 | int exHeight = std::max(0, std::min(3, Options::battleExplosionHeight)); |
| 1120 | int vertdec = 1000; //default flat explosion |
| 1121 | |
| 1122 | switch (exHeight) |
| 1123 | { |
| 1124 | case 1: |
| 1125 | vertdec = 30; |
| 1126 | break; |
| 1127 | case 2: |
| 1128 | vertdec = 10; |
| 1129 | break; |
| 1130 | case 3: |
| 1131 | vertdec = 5; |
| 1132 | } |
| 1133 | |
| 1134 | |
| 1135 | for (int fi = -90; fi <= 90; fi += 5) |
| 1136 | // for (int fi = 0; fi <= 0; fi += 10) |
| 1137 | { |
| 1138 | // raytrace every 3 degrees makes sure we cover all tiles in a circle. |
| 1139 | for (int te = 0; te <= 360; te += 3) |
| 1140 | { |
| 1141 | double cos_te = cos(te * M_PI / 180.0); |
| 1142 | double sin_te = sin(te * M_PI / 180.0); |
| 1143 | double sin_fi = sin(fi * M_PI / 180.0); |
| 1144 | double cos_fi = cos(fi * M_PI / 180.0); |
| 1145 | |
| 1146 | Tile *origin = _save->getTile(Position(centerX, centerY, centerZ)); |
| 1147 | double l = 0; |
| 1148 | double vx, vy, vz; |
| 1149 | int tileX, tileY, tileZ; |
| 1150 | power_ = power + 1; |
| 1151 | penetration = power_; |
| 1152 | while (power_ > 0 && l <= maxRadius) |
| 1153 | { |
| 1154 | vx = centerX + l * sin_te * cos_fi; |
| 1155 | vy = centerY + l * cos_te * cos_fi; |
| 1156 | vz = centerZ + l * sin_fi; |
| 1157 | |
| 1158 | tileZ = int(floor(vz)); |
| 1159 | tileX = int(floor(vx)); |
| 1160 | tileY = int(floor(vy)); |
| 1161 | |
| 1162 | Tile *dest = _save->getTile(Position(tileX, tileY, tileZ)); |
no test coverage detected