From 4c780d886747f5dee0ee405d1269ac80add17bfd Mon Sep 17 00:00:00 2001 From: wolfy852 Date: Sat, 2 Dec 2023 16:47:12 -0600 Subject: [PATCH] Hardcoding: Cloud logic --- src/k_kart.c | 5 + src/k_objects.h | 9 ++ src/objects/CMakeLists.txt | 1 + src/objects/cloud.c | 270 +++++++++++++++++++++++++++++++++++++ src/p_inter.c | 10 ++ src/p_mobj.c | 14 ++ 6 files changed, 309 insertions(+) create mode 100644 src/objects/cloud.c diff --git a/src/k_kart.c b/src/k_kart.c index 0054b2163..6f942afeb 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -12864,6 +12864,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { Obj_IceCubeInput(player); } + + Obj_PlayerCloudThink(player); + + Obj_PlayerBulbThink(player); + } void K_CheckSpectateStatus(boolean considermapreset) diff --git a/src/k_objects.h b/src/k_objects.h index 0b4b2ad85..ad0d43f23 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -358,6 +358,15 @@ void Obj_EMZRainGenerator(mobj_t *mo); void Obj_TrickBalloonMobjSpawn(mobj_t* mobj); void Obj_TrickBalloonTouchSpecial(mobj_t* special, mobj_t* toucher); +/* AHZ/AGZ/SSZ Clouds */ +void Obj_CloudSpawn(mobj_t *mobj); +void Obj_CloudClusterThink(mobj_t *mobj, mobjtype_t cloudtype); +void Obj_TulipSpawnerThink(mobj_t *mobj); +void Obj_PlayerCloudThink(player_t *player); +void Obj_PlayerBulbThink(player_t *player); +void Obj_CloudTouched(mobj_t *special, mobj_t *toucher); +void Obj_BulbTouched(mobj_t *special, mobj_t *toucher); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index d6b1798fd..04c4bc6b9 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -50,6 +50,7 @@ target_sources(SRB2SDL2 PRIVATE rocks.cpp emz-faucet.cpp trick-balloon.c + cloud.c ) add_subdirectory(versus) diff --git a/src/objects/cloud.c b/src/objects/cloud.c new file mode 100644 index 000000000..0f05f29fd --- /dev/null +++ b/src/objects/cloud.c @@ -0,0 +1,270 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour +// Copyright (C) 2022 by Kart Krew +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file cloud.c +/// \brief Launcher clouds and tulips used for Aerial Highlands, Avant Garden, and Sky Sanctuary. + +#include "../p_local.h" +#include "../k_objects.h" +#include "../g_game.h" +#include "../info.h" +#include "../s_sound.h" +#include "../r_main.h" +#include "../m_random.h" + + +#define BULB_ZTHRUST 96*FRACUNIT +#define CLOUD_ZTHRUST 32*FRACUNIT +#define CLOUDB_ZTHRUST 16*FRACUNIT + +void Obj_CloudSpawn(mobj_t *mobj) +{ + mobj->destscale = mapobjectscale * 4; + P_SetScale(mobj, mobj->destscale); +} + +void Obj_CloudClusterThink(mobj_t *mobj, mobjtype_t cloudtype) +{ + if (mobj->extravalue1) + return; + + mobj_t *cloud = P_SpawnMobj(mobj->x, mobj->y, mobj->z, cloudtype); + angle_t ang = mobj->angle; + UINT8 dist = 128; + + if (cloudtype == MT_AGZ_CLOUD) + cloud->scale *= 2; + + for (UINT8 i = 0; i < 4; i++) + { + fixed_t x = mobj->x + FixedMul(mapobjectscale, dist * FINECOSINE(ang >> ANGLETOFINESHIFT)); + fixed_t y = mobj->y + FixedMul(mapobjectscale, dist * FINESINE(ang >> ANGLETOFINESHIFT)); + + cloud = P_SpawnMobj(x, y, mobj->z, cloudtype); + + if (cloudtype == MT_AGZ_CLOUD) + { + cloud->scale *= 2; + cloud->frame = P_RandomRange(PR_DECORATION, 0, 3); + } + + ang += ANGLE_90; + } + + mobj->extravalue1 = 1; +} + +void Obj_TulipSpawnerThink(mobj_t *mobj) +{ + if (!mobj->tracer) + { + mobj->hnext = P_SpawnMobj(0, 0, 0, MT_AGZ_BULB_PART); + mobj->hnext->hnext = P_SpawnMobj(0, 0, 0, MT_AGZ_BULB_PART); + + P_SetMobjState(mobj->hnext, S_AGZBULB_BASE); + P_SetMobjState(mobj->hnext->hnext, S_AGZBULB_BASE); + + mobj->tracer = P_SpawnMobj(0, 0, 0, MT_AGZ_BULB_PART); + P_SetMobjState(mobj->tracer, S_AGZBULB_NEUTRAL); + } + + angle_t a = mobj->angle + ANG1*45; + mobj_t *part = mobj->hnext; + + while (part) + { + P_MoveOrigin(part, mobj->x, mobj->y, mobj->z); + part->angle = a; + part->scale = mobj->scale; + part->flags2 = mobj->flags2; + part->eflags = mobj->eflags; + a += ANG1*90; + part = part->hnext; + } + + mobj_t *b = mobj->tracer; + + P_MoveOrigin(b, mobj->x, mobj->y, mobj->z); + b->scale = mobj->scale; + b->flags2 = mobj->flags2; + b->eflags = mobj->eflags; + b->color = SKINCOLOR_MAGENTA; + + if (b->state == S_AGZBULB_ANIM2) + { + if (leveltime & 1) + b->colorized = true; + else + b->colorized = false; + } + else + b->colorized = false; +} + +void Obj_PlayerCloudThink(player_t *player) +{ + mobj_t *mo = player->mo; + + if (player->cloudbuf) + player->cloudbuf--; + + if (player->cloudlaunch) + { + player->cloudlaunch--; + + if (leveltime % 6 == 0) + P_SpawnMobj(mo->x + P_RandomRange(PR_DECORATION, -8, 8)*mapobjectscale, mo->y + P_RandomRange(PR_DECORATION, -8, 8)*mapobjectscale, mo->z, MT_DRIFTDUST); + } + + if (player->cloud) + { + player->cloud--; + P_InstaThrust(mo, 0, 0); + mo->momz = 0; + + if (!player->cloud) + { + if (!mo->tracer) + return; + + switch(mo->tracer->type) + { + case MT_AHZ_CLOUD: + P_SetObjectMomZ(mo, CLOUD_ZTHRUST, false); + break; + case MT_AGZ_CLOUD: + mo->momz = FixedMul(mapobjectscale, CLOUD_ZTHRUST * P_MobjFlip(mo->tracer)); + break; + case MT_SSZ_CLOUD: + P_SetObjectMomZ(mo, CLOUDB_ZTHRUST, false); + break; + default: + break; + } + P_SetObjectMomZ(mo, CLOUD_ZTHRUST, false); + player->cloudlaunch = TICRATE; + + P_InstaThrust(mo, mo->cusval, mo->cvmem); + } + } +} + +void Obj_PlayerBulbThink(player_t *player) +{ + mobj_t *mo = player->mo; + + if (player->tulipbuf) + player->tulipbuf--; + + if (player->tuliplaunch) + { + player->tuliplaunch--; + + if (leveltime % 2 == 0) + P_SpawnMobj(mo->x + P_RandomRange(PR_DECORATION, -8, 8)*mapobjectscale, mo->y + P_RandomRange(PR_DECORATION, -8, 8)*mapobjectscale, mo->z, MT_DRIFTDUST); + } + + if (player->tulip) + { + player->tulip -= 1; + P_MoveOrigin(mo, mo->tracer->x, mo->tracer->y, mo->tracer->z); + mo->flags &= ~MF_SHOOTABLE; + mo->renderflags |= RF_DONTDRAW; + } + + if (player->tulip == 1) // expired + { + + S_StartSound(mo, sfx_s3k81); + + for (UINT8 i = 1; i < 16; i++) + { + mobj_t *d = P_SpawnMobj(mo->x, mo->y, mo->z, MT_DRIFTDUST); + d->angle = (ANG1*360)/16 * i; + P_InstaThrust(d, d->angle, mapobjectscale*23); + d->momz = mapobjectscale*8*P_MobjFlip(mo->tracer); + } + + mo->renderflags &= ~RF_DONTDRAW; + mo->player->nocontrol = 0; + P_InstaThrust(mo, mo->tracer->extravalue2, mo->tracer->extravalue1); + mo->momz = FixedMul(mapobjectscale, BULB_ZTHRUST)*P_MobjFlip(mo->tracer); + + mo->flags |= MF_SHOOTABLE; + player->tuliplaunch = TICRATE; + player->tulipbuf = 8; + player->tulip = 0; + mo->tracer->target = NULL; + mo->tracer = NULL; + } +} + +void Obj_CloudTouched(mobj_t *special, mobj_t *toucher) +{ + player_t *player = toucher->player; + + if (player->cloudbuf || player->cloud) + return; + + player->cloud = TICRATE/8; + player->cloudbuf = TICRATE/3; + + for (UINT8 i = 1; i < 6; i++) + { + mobj_t *spawn = P_SpawnMobj(toucher->x + P_RandomRange(PR_DECORATION, -32, 32)*mapobjectscale, toucher->y + P_RandomRange(PR_DECORATION, -32, 32)*mapobjectscale, toucher->z, MT_DRIFTDUST); + spawn->angle = R_PointToAngle2(toucher->x, toucher->y, spawn->x, spawn->y); + P_InstaThrust(spawn, spawn->angle, P_RandomRange(PR_DECORATION, 1, 8)*mapobjectscale); + P_SetObjectMomZ(spawn, P_RandomRange(PR_DECORATION, 4, 10)<destscale = mapobjectscale * 3; + } + + toucher->cvmem = FixedHypot(toucher->momx, toucher->momy); + + if (toucher->cvmem) + toucher->cusval = R_PointToAngle2(0, 0, toucher->momx, toucher->momy); + + if (toucher->cvmem < mapobjectscale*8) + toucher->cvmem = mapobjectscale*8; + + toucher->tracer = special; + S_StartSound(toucher, sfx_s3k8a); + +} + +void Obj_BulbTouched(mobj_t *special, mobj_t *toucher) +{ + if (toucher->player->tulip || toucher->player->tulipbuf) + return; + + if (special && special->target) + return; // player already using it + + if (toucher->player->respawn.timer) + return; + + toucher->player->tulip = 8*2 +1; + + fixed_t spd = FixedHypot(toucher->momx, toucher->momy); + angle_t ang = R_PointToAngle2(0, 0, toucher->momx, toucher->momy); + + P_InstaThrust(toucher, 0, 0); + P_MoveOrigin(toucher, special->x, special->y, special->z); + toucher->player->nocontrol = 1; + toucher->tracer = special; + toucher->flags &= ~MF_SHOOTABLE; + toucher->renderflags |= RF_DONTDRAW; + special->target = toucher; + special->extravalue1 = spd; + special->extravalue2 = ang; + + S_StartSound(special, sfx_s254); + + // set bulb state: + P_SetMobjState(special->tracer, S_AGZBULB_ANIM1); +} \ No newline at end of file diff --git a/src/p_inter.c b/src/p_inter.c index dc955cfc7..48075e1bb 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -959,6 +959,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) Obj_DLZRocketSpecial(special, player); return; + case MT_AHZ_CLOUD: + case MT_AGZ_CLOUD: + case MT_SSZ_CLOUD: + Obj_CloudTouched(special, player); + return; + + case MT_AGZ_BULB: + Obj_BulbTouched(special, player); + return; + case MT_BALLSWITCH_BALL: { Obj_BallSwitchTouched(special, toucher); diff --git a/src/p_mobj.c b/src/p_mobj.c index 689970281..f573335e1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10272,6 +10272,16 @@ static boolean P_MobjRegularThink(mobj_t *mobj) Obj_GPZSeasawThink(mobj); break; + case MT_AHZ_CLOUDCLUSTER: + case MT_AGZ_CLOUDCLUSTER: + case MT_SSZ_CLOUDCLUSTER: + Obj_CloudClusterThink(mobj, mobj->type); + break; + + case MT_AGZ_BULB: + Obj_TulipSpawnerThink(mobj); + break; + case MT_BALLSWITCH_BALL: { Obj_BallSwitchThink(mobj); @@ -11803,6 +11813,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_WATERPALACETURBINE: Obj_WPZTurbineSpawn(mobj); break; + case MT_AHZ_CLOUDCLUSTER: + case MT_SSZ_CLOUDCLUSTER: + Obj_CloudSpawn(mobj); + break; case MT_SNEAKERPANEL: Obj_SneakerPanelSpawn(mobj); break;