Merge branch 'dialogue-2' into 'master'

Dialogue 2

See merge request KartKrew/Kart!1421
This commit is contained in:
Oni 2023-08-26 03:42:10 +00:00
commit 3f596a24ba
20 changed files with 671 additions and 57 deletions

View file

@ -149,6 +149,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
k_mapuser.c
k_powerup.cpp
k_hitlag.c
k_dialogue.cpp
music.cpp
music_manager.cpp
)

View file

@ -44,6 +44,8 @@
#include "../k_bot.h"
#include "../z_zone.h"
#include "../music.h"
#include "../r_draw.h"
#include "../k_dialogue.hpp"
#include "call-funcs.hpp"
@ -664,6 +666,50 @@ bool CallFunc_CameraWait(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::
return true; // Execution interrupted
}
/*--------------------------------------------------
bool CallFunc_DialogueWaitDismiss(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
Pauses the thread until the current
dialogue box is dismissed.
--------------------------------------------------*/
bool CallFunc_DialogueWaitDismiss(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
{
(void)argV;
(void)argC;
g_dialogue.SetDismissable(true);
thread->state = {
ACSVM::ThreadState::WaitTag,
0,
ACS_TAGTYPE_DIALOGUE
};
return true; // Execution interrupted
}
/*--------------------------------------------------
bool CallFunc_DialogueWaitText(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
Pauses the thread until the current
dialogue box finishes rendering its text.
--------------------------------------------------*/
bool CallFunc_DialogueWaitText(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
{
(void)argV;
(void)argC;
g_dialogue.SetDismissable(false);
thread->state = {
ACSVM::ThreadState::WaitTag,
1,
ACS_TAGTYPE_DIALOGUE
};
return true; // Execution interrupted
}
/*--------------------------------------------------
bool CallFunc_ChangeFloor(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
@ -1858,6 +1904,84 @@ bool CallFunc_AddBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word
return false;
}
/*--------------------------------------------------
bool CallFunc_DialogueSetSpeaker(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
Set the dialogue speaker to a skin.
--------------------------------------------------*/
bool CallFunc_DialogueSetSpeaker(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
{
ACSVM::MapScope *map = nullptr;
ACSVM::String *skinStr = nullptr;
const char *skinName = nullptr;
int spriteFrame = 0;
(void)argC;
map = thread->scopeMap;
skinStr = map->getString(argV[0]);
skinName = skinStr->str;
spriteFrame = argV[1];
g_dialogue.SetSpeaker(skinName, spriteFrame);
return false;
}
/*--------------------------------------------------
bool CallFunc_DialogueSetCustomSpeaker(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
Set the dialogue speaker to specific graphics.
--------------------------------------------------*/
bool CallFunc_DialogueSetCustomSpeaker(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
{
ACSVM::MapScope *map = nullptr;
ACSVM::String *nametagStr = nullptr;
const char *nametag = nullptr;
ACSVM::String *patchStr = nullptr;
const char *patchName = nullptr;
patch_t *patch = nullptr;
ACSVM::String *colorStr = nullptr;
const char *colorName = nullptr;
skincolornum_t colorID = SKINCOLOR_NONE;
UINT8 *colormap = nullptr;
ACSVM::String *voiceStr = nullptr;
const char *voiceName = nullptr;
sfxenum_t voiceID = sfx_ktalk;
(void)argC;
map = thread->scopeMap;
nametagStr = map->getString(argV[0]);
nametag = nametagStr->str;
patchStr = map->getString(argV[1]);
patchName = patchStr->str;
patch = static_cast<patch_t *>( W_CachePatchName(patchName, PU_CACHE) );
colorStr = map->getString(argV[2]);
colorName = colorStr->str;
if (ACS_GetColorFromString(colorName, &colorID) == true)
{
colormap = R_GetTranslationColormap(TC_DEFAULT, colorID, GTC_CACHE);
}
voiceStr = map->getString(argV[3]);
voiceName = voiceStr->str;
ACS_GetSFXFromString(voiceName, &voiceID);
g_dialogue.SetSpeaker(nametag, patch, colormap, voiceID);
return false;
}
/*--------------------------------------------------
bool CallFunc_StopLevelExit(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
@ -1898,7 +2022,29 @@ bool CallFunc_ExitLevel(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::W
if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
return false;
}
/*--------------------------------------------------
bool CallFunc_DialogueNewText(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
Change the current dialogue text.
--------------------------------------------------*/
bool CallFunc_DialogueNewText(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
{
ACSVM::MapScope *map = nullptr;
ACSVM::String *textStr = nullptr;
const char *text = nullptr;
(void)argC;
map = thread->scopeMap;
textStr = map->getString(argV[0]);
text = textStr->str;
g_dialogue.NewText(text);
return false;
}

View file

@ -42,6 +42,8 @@ bool CallFunc_ThingCount(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::
bool CallFunc_TagWait(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_PolyWait(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_CameraWait(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_DialogueWaitDismiss(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_DialogueWaitText(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_ChangeFloor(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_ChangeCeiling(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_LineSide(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
@ -93,6 +95,10 @@ bool CallFunc_MusicPlay(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::W
bool CallFunc_MusicStopAll(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_MusicRemap(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_DialogueSetSpeaker(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_DialogueSetCustomSpeaker(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_DialogueNewText(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_GetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_SetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_GetSideProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);

View file

@ -27,6 +27,7 @@
#include "../w_wad.h"
#include "../z_zone.h"
#include "../p_local.h"
#include "../k_dialogue.hpp"
#include "environment.hpp"
#include "thread.hpp"
@ -176,6 +177,12 @@ Environment::Environment()
addFuncDataACS0( 508, addCallFunc(CallFunc_MusicPlay));
addFuncDataACS0( 509, addCallFunc(CallFunc_MusicStopAll));
addFuncDataACS0( 510, addCallFunc(CallFunc_MusicRemap));
addFuncDataACS0( 600, addCallFunc(CallFunc_DialogueSetSpeaker));
addFuncDataACS0( 601, addCallFunc(CallFunc_DialogueSetCustomSpeaker));
addFuncDataACS0( 602, addCallFunc(CallFunc_DialogueNewText));
addFuncDataACS0( 603, addCallFunc(CallFunc_DialogueWaitDismiss));
addFuncDataACS0( 604, addCallFunc(CallFunc_DialogueWaitText));
}
ACSVM::Thread *Environment::allocThread()
@ -289,6 +296,20 @@ bool Environment::checkTag(ACSVM::Word type, ACSVM::Word tag)
return (camera->tracer == nullptr || P_MobjWasRemoved(camera->tracer) == true);
}
case ACS_TAGTYPE_DIALOGUE:
{
if (tag == 0) // cheeky reuse
{
// wait for dismissal
return (!g_dialogue.Active());
}
else
{
// wait for text to finish
return (g_dialogue.TextDone());
}
}
}
return true;

View file

@ -53,6 +53,7 @@ enum acs_tagType_e
ACS_TAGTYPE_POLYOBJ,
ACS_TAGTYPE_SECTOR,
ACS_TAGTYPE_CAMERA,
ACS_TAGTYPE_DIALOGUE,
};
class ThreadInfo : public ACSVM::ThreadInfo

View file

@ -84,6 +84,7 @@
#include "k_vote.h"
#include "k_serverstats.h"
#include "music.h"
#include "k_dialogue.h"
#ifdef HWRENDER
#include "hardware/hw_main.h" // 3D View Rendering
@ -1012,6 +1013,8 @@ void D_ClearState(void)
if (gamedata && gamedata->deferredsave)
G_SaveGameData();
K_UnsetDialogue();
G_SetGamestate(GS_NULL);
wipegamestate = GS_NULL;
}

View file

@ -6657,6 +6657,7 @@ struct int_const_s const INT_CONST[] = {
{"SKSKSLOW",SKSKSLOW}, // Overtake taunt
{"SKSKHITM",SKSKHITM}, // Hit confirm taunt
{"SKSKPOWR",SKSKPOWR}, // Power item taunt
{"SKSKTALK",SKSKTALK}, // Dialogue
// 3D Floor/Fake Floor/FOF/whatever flags
{"FOF_EXISTS",FOF_EXISTS}, ///< Always set, to check for validity.

View file

@ -915,6 +915,7 @@ char spr2names[NUMPLAYERSPRITES][5] =
"SIGN", // Finish signpost
"XTRA", // Three Faces of Darkness
"TALK", // Dialogue
};
playersprite_t free_spr2 = SPR2_FIRSTFREESLOT;
@ -956,6 +957,7 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
0, // SPR2_SIGN
0, // SPR2_XTRA
0, // SPR2_TALK
};
// Doesn't work with g++, needs actionf_p1 (don't modify this comment)

View file

@ -1468,6 +1468,7 @@ typedef enum playersprite
SPR2_DEAD,
SPR2_SIGN,
SPR2_XTRA,
SPR2_TALK,
SPR2_FIRSTFREESLOT,
SPR2_LASTFREESLOT = 0x7f,

350
src/k_dialogue.cpp Normal file
View file

@ -0,0 +1,350 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) by Sonic Team Junior
// Copyright (C) by Kart Krew
// Copyright (C) by Sally "TehRealSalt" Cochenour
//
// 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 k_dialogue.cpp
/// \brief Basic text prompts
#include "k_dialogue.hpp"
#include "k_dialogue.h"
#include <string>
#include <algorithm>
#include "info.h"
#include "sounds.h"
#include "g_game.h"
#include "v_video.h"
#include "r_draw.h"
#include "m_easing.h"
#include "r_skins.h"
#include "s_sound.h"
#include "z_zone.h"
#include "k_hud.h"
#include "v_draw.hpp"
#include "acs/interface.h"
using srb2::Dialogue;
void Dialogue::Init(void)
{
active = true;
syllable = true;
}
void Dialogue::SetSpeaker(void)
{
// Unset speaker
speaker.clear();
portrait = nullptr;
portraitColormap = nullptr;
voiceSfx = sfx_ktalk;
}
void Dialogue::SetSpeaker(std::string skinName, int portraitID)
{
Init();
// Set speaker based on a skin
int skinID = -1;
if (!skinName.empty())
{
skinID = R_SkinAvailable(skinName.c_str());
}
if (skinID >= 0 && skinID < numskins)
{
const skin_t *skin = &skins[skinID];
const spritedef_t *sprdef = &skin->sprites[SPR2_TALK];
if (sprdef->numframes > 0)
{
portraitID %= sprdef->numframes;
}
const spriteframe_t *sprframe = &sprdef->spriteframes[portraitID];
speaker = skin->realname;
portrait = static_cast<patch_t *>( W_CachePatchNum(sprframe->lumppat[0], PU_CACHE) );
portraitColormap = R_GetTranslationColormap(skinID, static_cast<skincolornum_t>(skin->prefcolor), GTC_CACHE);
voiceSfx = skin->soundsid[ S_sfx[sfx_ktalk].skinsound ];
}
else
{
SetSpeaker();
}
}
void Dialogue::SetSpeaker(std::string name, patch_t *patch, UINT8 *colormap, sfxenum_t voice)
{
Init();
// Set custom speaker
speaker = name;
if (speaker.empty())
{
portrait = nullptr;
portraitColormap = nullptr;
voiceSfx = sfx_ktalk;
return;
}
portrait = patch;
portraitColormap = colormap;
voiceSfx = voice;
}
void Dialogue::NewText(std::string newText)
{
Init();
newText = V_ScaledWordWrap(
290 << FRACBITS,
FRACUNIT, FRACUNIT, FRACUNIT,
0, HU_FONT,
newText.c_str()
);
text.clear();
textDest = newText;
std::reverse(textDest.begin(), textDest.end());
textTimer = kTextPunctPause;
textSpeed = kTextSpeedDefault;
textDone = false;
}
bool Dialogue::Active(void)
{
return active;
}
bool Dialogue::TextDone(void)
{
return textDone;
}
bool Dialogue::Dismissable(void)
{
return dismissable;
}
void Dialogue::SetDismissable(bool value)
{
dismissable = value;
}
void Dialogue::WriteText(void)
{
bool voicePlayed = false;
textTimer -= textSpeed;
while (textTimer <= 0 && !textDest.empty())
{
char c = textDest.back();
text.push_back(c);
if (voicePlayed == false
&& std::isprint(c)
&& c != ' ')
{
if (syllable)
{
S_StopSoundByNum(voiceSfx);
S_StartSound(nullptr, voiceSfx);
}
syllable = !syllable;
voicePlayed = true;
}
if (c == '.' || c == ',' || c == ';' || c == '!' || c == '?')
{
// slow down for punctuation
textTimer += kTextPunctPause;
}
else
{
textTimer += FRACUNIT;
}
textDest.pop_back();
}
textDone = (textTimer <= 0 && textDest.empty());
}
bool Dialogue::Held(void)
{
return ((players[serverplayer].cmd.buttons & BT_VOTE) == BT_VOTE);
}
bool Dialogue::Pressed(void)
{
return (
((players[serverplayer].cmd.buttons & BT_VOTE) == BT_VOTE) &&
((players[serverplayer].oldcmd.buttons & BT_VOTE) == 0)
);
}
void Dialogue::CompleteText(void)
{
while (!textDest.empty())
{
text.push_back( textDest.back() );
textDest.pop_back();
}
textTimer = 0;
textDone = true;
}
void Dialogue::Tick(void)
{
if (Active())
{
if (slide < FRACUNIT)
{
slide += kSlideSpeed;
}
}
else
{
if (slide > 0)
{
slide -= kSlideSpeed;
if (slide <= 0)
{
Unset();
}
}
}
slide = std::clamp(slide, 0, FRACUNIT);
if (slide != FRACUNIT)
{
return;
}
WriteText();
if (Dismissable() == true)
{
if (Pressed() == true)
{
if (TextDone())
{
Dismiss();
}
else
{
CompleteText();
}
}
}
}
void Dialogue::Draw(void)
{
if (slide == 0)
{
return;
}
srb2::Draw drawer =
srb2::Draw(
0, FixedToFloat(Easing_OutCubic(slide, -78 * FRACUNIT, 0))
).flags(V_SNAPTOTOP);
drawer.patch("TUTDIAG1");
if (portrait != nullptr)
{
drawer
.xy(10, 41)
.colormap(portraitColormap)
.patch(portrait);
}
drawer
.xy(45, 39)
.font(srb2::Draw::Font::kConsole)
.text( speaker.c_str() );
drawer
.xy(10, 3)
.font(srb2::Draw::Font::kConsole)
.text( text.c_str() );
if (Dismissable())
{
if (TextDone())
{
drawer
.xy(304, 7)
.patch("TUTDIAG2");
}
K_drawButton(
FloatToFixed(drawer.x() + 303),
FloatToFixed(drawer.y() + 39),
V_SNAPTOTOP,
kp_button_z[0], Held()
);
}
}
void Dialogue::Dismiss(void)
{
active = false;
text.clear();
textDest.clear();
}
void Dialogue::Unset(void)
{
Dismiss();
SetSpeaker();
}
/*
Ideally, the Dialogue class would be on player_t instead of in global space
for full multiplayer compatibility, but right now it's only being used for
the tutorial, and I don't feel like writing network code. If you feel like
doing that, then you can remove g_dialogue entirely.
*/
Dialogue g_dialogue;
void K_UnsetDialogue(void)
{
g_dialogue.Unset();
}
void K_DrawDialogue(void)
{
g_dialogue.Draw();
}
void K_TickDialogue(void)
{
g_dialogue.Tick();
}

32
src/k_dialogue.h Normal file
View file

@ -0,0 +1,32 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) by Sonic Team Junior
// Copyright (C) by Kart Krew
// Copyright (C) by Sally "TehRealSalt" Cochenour
//
// 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 k_dialogue.h
/// \brief Basic text prompts
#ifndef __K_DIALOGUE__
#define __K_DIALOGUE__
#include "doomtype.h"
#include "doomdef.h"
#ifdef __cplusplus
extern "C" {
#endif
void K_UnsetDialogue(void);
void K_DrawDialogue(void);
void K_TickDialogue(void);
#ifdef __cplusplus
} // extern "C"
#endif
#endif //__K_DIALOGUE__

88
src/k_dialogue.hpp Normal file
View file

@ -0,0 +1,88 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) by Sonic Team Junior
// Copyright (C) by Kart Krew
// Copyright (C) by Sally "TehRealSalt" Cochenour
//
// 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 k_dialogue.hpp
/// \brief Basic text prompts
#ifndef __K_DIALOGUE_HPP__
#define __K_DIALOGUE_HPP__
#include <string>
#include "doomdef.h"
#include "doomtype.h"
#include "typedef.h"
#include "sounds.h"
#include "v_video.h"
namespace srb2
{
class Dialogue
{
private:
patch_t *bgPatch;
patch_t *confirmPatch;
std::string speaker;
patch_t *portrait;
UINT8 *portraitColormap;
sfxenum_t voiceSfx;
std::string text;
std::string textDest;
bool active;
fixed_t slide;
fixed_t textTimer;
fixed_t textSpeed;
bool textDone;
bool syllable;
bool dismissable;
void Init(void);
//void Unset(void);
void WriteText(void);
void CompleteText(void);
bool Pressed(void);
bool Held(void);
public:
static constexpr fixed_t kTextSpeedDefault = FRACUNIT;
static constexpr fixed_t kTextPunctPause = (FRACUNIT * TICRATE * 2) / 5;
static constexpr fixed_t kSlideSpeed = FRACUNIT / (TICRATE / 5);
void SetSpeaker(void);
void SetSpeaker(std::string skinName, int portraitID);
void SetSpeaker(std::string name, patch_t *patch, UINT8 *colormap, sfxenum_t voice);
void NewText(std::string newText);
bool Active(void);
bool TextDone(void);
bool Dismissable(void);
void SetDismissable(bool value);
void Tick(void);
void Draw(void);
void Dismiss(void);
void Unset(void);
};
}; // namespace srb2
extern srb2::Dialogue g_dialogue;
#endif //__K_DIALOGUE_HPP__

View file

@ -8250,7 +8250,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
}
}
if (player->stealingtimer == 0
&& player->rocketsneakertimer
&& onground == true)

View file

@ -105,6 +105,7 @@
#include "k_rank.h"
#include "k_mapuser.h"
#include "music.h"
#include "k_dialogue.h"
// Replay names have time
#if !defined (UNDER_CE)
@ -1260,7 +1261,6 @@ static void P_LoadSidedefs(UINT8 *data)
case 425: // Calls P_SetMobjState on calling mobj
case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors
case 443: // Calls a named Lua function
case 459: // Control text prompt (named tag)
case 461: // Spawns an object on the map based on texture offsets
case 463: // Colorizes an object
case 475: // ACS_Execute
@ -5800,7 +5800,7 @@ static void P_ConvertBinaryLinedefTypes(void)
lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
break;
case 437: //Disable player control
lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
lines[i].args[0] = ((sides[lines[i].sidenum[0]].textureoffset >> FRACBITS) != 0);
break;
case 438: //Change object size
lines[i].args[0] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS;
@ -5950,25 +5950,6 @@ static void P_ConvertBinaryLinedefTypes(void)
lines[i].args[3] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : 0;
lines[i].args[4] = !!(lines[i].flags & ML_NOSKEW);
break;
case 459: //Control text prompt
lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
if (lines[i].flags & ML_BLOCKPLAYERS)
lines[i].args[3] |= TMP_CLOSE;
if (lines[i].flags & ML_SKEWTD)
lines[i].args[3] |= TMP_RUNPOSTEXEC;
if (lines[i].flags & ML_TFERLINE)
lines[i].args[3] |= TMP_CALLBYNAME;
if (lines[i].flags & ML_NOSKEW)
lines[i].args[3] |= TMP_KEEPCONTROLS;
if (lines[i].flags & ML_MIDPEG)
lines[i].args[3] |= TMP_KEEPREALTIME;
/*if (lines[i].flags & ML_NOCLIMB)
lines[i].args[3] |= TMP_ALLPLAYERS;
if (lines[i].flags & ML_MIDSOLID)
lines[i].args[3] |= TMP_FREEZETHINKERS;*/
lines[i].args[4] = (lines[i].sidenum[1] != 0xFFFF) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : tag;
break;
case 460: //Award rings
lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
@ -8278,6 +8259,8 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
// Close text prompt before freeing the old level
F_EndTextPrompt(false, true);
K_UnsetDialogue();
LUA_InvalidateLevel();
for (ss = sectors; sectors+numsectors != ss; ss++)

View file

@ -3284,13 +3284,10 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
}
break;
case 437: // Disable Player Controls
case 437: // Toggle Player Controls
if (mo && mo->player)
{
UINT16 fractime = (UINT16)(args[0]);
if (fractime < 1)
fractime = 1; //instantly wears off upon leaving
mo->player->nocontrol = fractime;
mo->player->nocontrol = ((args[0] == 0) ? UINT16_MAX : 0);
}
break;
@ -4071,33 +4068,6 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
}
break;
case 459: // Control Text Prompt
// console player only
if (mo && mo->player && P_IsLocalPlayer(mo->player))
{
INT32 promptnum = max(0, args[1] - 1);
INT32 pagenum = max(0, args[2] - 1);
INT32 postexectag = abs(args[4]);
boolean closetextprompt = (args[3] & TMP_CLOSE);
//boolean allplayers = (args[3] & TMP_ALLPLAYERS);
boolean runpostexec = (args[3] & TMP_RUNPOSTEXEC);
boolean blockcontrols = !(args[3] & TMP_KEEPCONTROLS);
boolean freezerealtime = !(args[3] & TMP_KEEPREALTIME);
//boolean freezethinkers = (args[3] & TMP_FREEZETHINKERS);
boolean callbynamedtag = (args[3] & TMP_CALLBYNAME);
if (closetextprompt)
F_EndTextPrompt(false, false);
else
{
if (callbynamedtag && stringargs[0] && stringargs[0][0])
F_GetPromptPageByNamedTag(stringargs[0], &promptnum, &pagenum);
F_StartTextPrompt(promptnum, pagenum, mo, runpostexec ? postexectag : 0, blockcontrols, freezerealtime);
}
}
break;
case 460: // Award rings
{
if (gametyperules & GTR_SPHERES)

View file

@ -43,6 +43,7 @@
#include "acs/interface.h"
#include "k_objects.h"
#include "music.h"
#include "k_dialogue.h"
#ifdef PARANOIA
#include "deh_tables.h" // MOBJTYPE_LIST
@ -1033,6 +1034,11 @@ void P_Ticker(boolean run)
P_RunChaseCameras();
}
if (run)
{
K_TickDialogue();
}
LUA_HOOK(PostThinkFrame);
if (run)

View file

@ -4335,15 +4335,13 @@ void P_PlayerThink(player_t *player)
if (!(--player->nocontrol))
{
if (player->pflags & PF_FAULT)
{
{
player->pflags &= ~PF_FAULT;
player->mo->renderflags &= ~RF_DONTDRAW;
player->mo->flags &= ~MF_NOCLIPTHING;
}
}
}
else
player->nocontrol = 0;
// Flash player after being hit.
if (!(player->hyudorotimer // SRB2kart - fixes Hyudoro not flashing when it should.

View file

@ -1439,6 +1439,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"kslow", false, 64, 32, -1, NULL, 0, SKSKSLOW, -1, LUMPERROR, ""},
{"khitem", false, 128, 32, -1, NULL, 0, SKSKHITM, -1, LUMPERROR, ""},
{"kgloat", false, 64, 48, -1, NULL, 0, SKSKPOWR, -1, LUMPERROR, ""},
{"ktalk", false, 64, 48, -1, NULL, 0, SKSKTALK, -1, LUMPERROR, ""},
// skin sounds free slots to add sounds at run time (Boris HACK!!!)
// initialized to NULL

View file

@ -56,6 +56,7 @@ typedef enum
SKSKSLOW, // Overtake taunt
SKSKHITM, // Hit confirm taunt
SKSKPOWR, // Power item taunt
SKSKTALK,
NUMSKINSOUNDS
} skinsound_t;
@ -1506,6 +1507,7 @@ typedef enum
sfx_kslow,
sfx_khitem,
sfx_kgloat,
sfx_ktalk,
// free slots for S_AddSoundFx() at run-time --------------------
sfx_freeslot0,

View file

@ -52,6 +52,7 @@
#include "k_zvote.h"
#include "music.h"
#include "i_sound.h"
#include "k_dialogue.h"
UINT16 objectsdrawn = 0;
@ -1244,6 +1245,8 @@ static void ST_overlayDrawer(void)
}
K_DrawMidVote();
K_DrawDialogue();
}
void ST_DrawDemoTitleEntry(void)