| 3195 | } |
| 3196 | |
| 3197 | void PlayerShipSpewPartSub(object *obj, bsp_info *submodel, float magnitude) { |
| 3198 | vector rand_vec; |
| 3199 | int subobjnum = submodel - Poly_models[obj->rtype.pobj_info.model_num].submodel; |
| 3200 | int i; |
| 3201 | int visnum; |
| 3202 | |
| 3203 | ASSERT(subobjnum > -1 && subobjnum < Poly_models[obj->rtype.pobj_info.model_num].n_models); |
| 3204 | |
| 3205 | // first go through all children. |
| 3206 | // find child index, and use that index into the submodel array of the polymodel to pass a new submodel down |
| 3207 | // the chain. |
| 3208 | i = 0; |
| 3209 | while (i < submodel->num_children) { |
| 3210 | PlayerShipSpewPartSub(obj, &Poly_models[obj->rtype.pobj_info.model_num].submodel[submodel->children[i]], magnitude); |
| 3211 | i++; |
| 3212 | } |
| 3213 | |
| 3214 | rand_vec.x = (float)(D3_RAND_MAX / 2 - ps_rand()); |
| 3215 | if (obj->movement_type != MT_PHYSICS) |
| 3216 | rand_vec.y = (float)((float)ps_rand() / 2.0); // A habit of moving upward |
| 3217 | else |
| 3218 | rand_vec.y = (float)((float)D3_RAND_MAX / 1.5f - (float)ps_rand()); // A habit of moving upward |
| 3219 | rand_vec.z = (float)(D3_RAND_MAX / 2 - ps_rand()); |
| 3220 | vm_NormalizeVectorFast(&rand_vec); |
| 3221 | |
| 3222 | object *subobj = CreateSubobjectDebrisDirected(obj, subobjnum, &rand_vec, magnitude); |
| 3223 | if (subobj) { |
| 3224 | // create mini-explosion at start of debris fall. |
| 3225 | vector newpos = subobj->pos + submodel->offset; |
| 3226 | visnum = CreateFireball(&newpos, MED_EXPLOSION_INDEX, subobj->roomnum, VISUAL_FIREBALL); |
| 3227 | if (visnum >= 0) { |
| 3228 | VisEffects[visnum].size *= (2.5f * (magnitude / MAX_EXPLOSION_MAG)); |
| 3229 | VisEffects[visnum].lifeleft *= 2.0f; |
| 3230 | rand_vec = (-rand_vec) * (magnitude * 25.0f); |
| 3231 | phys_apply_force(obj, &rand_vec); |
| 3232 | // mprintf(0, "Breakoff fireball size: %f, lifeleft: %f\n", Objects[objnum].size, Objects[objnum].lifeleft); |
| 3233 | } |
| 3234 | } |
| 3235 | |
| 3236 | // mark subobject dead |
| 3237 | obj->rtype.pobj_info.subobj_flags &= (~(1 << subobjnum)); |
| 3238 | // mprintf(0, "%d:sobj=%08x\n", subobjnum, obj->rtype.pobj_info.subobj_flags); |
| 3239 | } |
| 3240 | |
| 3241 | // Moves death camera a certain distance based off of direction from vec from |
| 3242 | // the player. returns new dist |
no test coverage detected