diff --git a/src/d_player.h b/src/d_player.h index 755926480ae9c2b2b90383659ec079230e48a881..6df6689c5fcf4f1085511218d7f19047cd8a7c0f 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -245,7 +245,8 @@ typedef enum CR_MINECART, CR_ROLLOUT, CR_PTERABYTE, - CR_DUSTDEVIL + CR_DUSTDEVIL, + CR_FAN } carrytype_t; // pw_carry // Player powers. (don't edit this comment) diff --git a/src/deh_tables.c b/src/deh_tables.c index e45d552c9e601461e5c29025d9e7cb662ce966c0..11d8b1a0147aebf3e1dfb3cb5251324ebd76d6e9 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5119,6 +5119,7 @@ struct int_const_s const INT_CONST[] = { {"CR_ROLLOUT",CR_ROLLOUT}, {"CR_PTERABYTE",CR_PTERABYTE}, {"CR_DUSTDEVIL",CR_DUSTDEVIL}, + {"CR_FAN",CR_FAN}, // Ring weapons (ringweapons_t) // Useful for A_GiveWeapon diff --git a/src/p_map.c b/src/p_map.c index 1a8494deafadbeb6ffb7d76069b9fd1c9526a280..2bb02503f464fde0b166e6940e9c40ad166a171c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -505,11 +505,12 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) if (flipval*object->momz > FixedMul(speed, spring->scale)) object->momz = flipval*FixedMul(speed, spring->scale); - if (p && !p->powers[pw_tailsfly]) // doesn't reset anim for Tails' flight + if (p && !p->powers[pw_tailsfly] && !p->powers[pw_carry]) // doesn't reset anim for Tails' flight { P_ResetPlayer(p); - if (p->panim != PA_FALL) - P_SetPlayerMobjState(object, S_PLAY_FALL); + P_SetPlayerMobjState(object, S_PLAY_FALL); + P_SetTarget(&object->tracer, spring); + p->powers[pw_carry] = CR_FAN; } break; case MT_STEAM: // Steam diff --git a/src/p_spec.c b/src/p_spec.c index 259b15e0b431019e2257b518cdde5448d26d6e63..3207ddb95b5d8c724a87a678e812c5e9f7cc4a93 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4965,9 +4965,13 @@ static void P_EvaluateSpecialFlags(player_t *player, sector_t *sector, sector_t if (player->mo->momz > mobjinfo[MT_FAN].mass) player->mo->momz = mobjinfo[MT_FAN].mass; - P_ResetPlayer(player); - if (player->panim != PA_FALL) + if (!player->powers[pw_carry]) + { + P_ResetPlayer(player); P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + P_SetTarget(&player->mo->tracer, player->mo); + player->powers[pw_carry] = CR_FAN; + } } if (sector->specialflags & SSF_SUPERTRANSFORM) { diff --git a/src/p_user.c b/src/p_user.c index fa42568cad316519ea09fdab2da736b09a7291d8..e48cb47eae6b0fcbc6b5bf8ece8e56e8ed705da4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1966,22 +1966,22 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->angle = (mobj->player ? mobj->player->drawangle : mobj->angle); ghost->rollangle = mobj->rollangle; - + ghost->sprite = mobj->sprite; ghost->sprite2 = mobj->sprite2; ghost->frame = mobj->frame; ghost->tics = -1; ghost->frame &= ~FF_TRANSMASK; ghost->frame |= tr_trans50<<FF_TRANSSHIFT; - + ghost->renderflags = mobj->renderflags; ghost->blendmode = mobj->blendmode; - + ghost->spritexscale = mobj->spritexscale; ghost->spriteyscale = mobj->spriteyscale; ghost->spritexoffset = mobj->spritexoffset; ghost->spriteyoffset = mobj->spriteyoffset; - + ghost->fuse = ghost->info->damage; ghost->skin = mobj->skin; @@ -12589,6 +12589,29 @@ void P_PlayerAfterThink(player_t *player) break; } + case CR_FAN: + { + fixed_t zdist; + mobj_t *mo = player->mo, *fan = player->mo->tracer; + + if (!(player->pflags & PF_JUMPSTASIS)) + player->pflags |= PF_JUMPSTASIS; + + if (fan->eflags & MFE_VERTICALFLIP) + zdist = (mo->z + mo->height) - (fan->z + fan->height); + else + zdist = mo->z - fan->z; + + if ((fan->type != MT_FAN && !P_PlayerTouchingSectorSpecialFlag(player, SSF_FAN)) + || (fan->type == MT_FAN && (abs(mo->x - fan->x) > fan->radius || abs(mo->y - fan->y) > fan->radius || zdist > (fan->health << FRACBITS)))) + { + P_SetTarget(&player->mo->tracer, NULL); + player->pflags &= ~PF_JUMPSTASIS; + player->powers[pw_carry] = CR_NONE; + break; + } + break; + } case CR_ROLLOUT: { mobj_t *mo = player->mo, *rock = player->mo->tracer;