aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--courtroom.cpp132
-rw-r--r--courtroom.h6
-rw-r--r--datatypes.h3
-rw-r--r--server/aoprotocol.py26
-rw-r--r--server/area_manager.py7
5 files changed, 156 insertions, 18 deletions
diff --git a/courtroom.cpp b/courtroom.cpp
index 435dcd34..dd6c1601 100644
--- a/courtroom.cpp
+++ b/courtroom.cpp
@@ -178,6 +178,9 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_showname_enable->setChecked(ao_app->get_showname_enabled_by_default());
ui_showname_enable->setText("Custom shownames");
+ ui_pre_non_interrupt = new QCheckBox(this);
+ ui_pre_non_interrupt->setText("No Intrpt");
+
ui_custom_objection = new AOButton(this, ao_app);
ui_realization = new AOButton(this, ao_app);
ui_mute = new AOButton(this, ao_app);
@@ -551,6 +554,9 @@ void Courtroom::set_widgets()
set_size_and_pos(ui_pre, "pre");
ui_pre->setText("Pre");
+ set_size_and_pos(ui_pre_non_interrupt, "pre_no_interrupt");
+ ui_pre_non_interrupt->setText("No Intrpt");
+
set_size_and_pos(ui_flip, "flip");
set_size_and_pos(ui_guard, "guard");
@@ -1012,7 +1018,8 @@ void Courtroom::on_chat_return_pressed()
//showname#
//other_charid#
- //self_offset#%
+ //self_offset#
+ //noninterrupting_preanim#%
QStringList packet_contents;
@@ -1051,7 +1058,7 @@ void Courtroom::on_chat_return_pressed()
else
f_emote_mod = 2;
}
- else if (ui_pre->isChecked())
+ else if (ui_pre->isChecked() and !ui_pre_non_interrupt->isChecked())
{
if (f_emote_mod == 0)
f_emote_mod = 1;
@@ -1134,6 +1141,22 @@ void Courtroom::on_chat_return_pressed()
packet_contents.append(QString::number(offset_with_pair));
}
+ if (ui_pre_non_interrupt->isChecked() and ui_pre->isChecked())
+ {
+ if (ui_ic_chat_name->text().isEmpty())
+ {
+ packet_contents.append("");
+ }
+
+ if (!(other_charid > -1 && other_charid != m_cid))
+ {
+ packet_contents.append("-1");
+ packet_contents.append("0");
+ }
+
+ packet_contents.append("1");
+ }
+
ao_app->send_server_packet(new AOPacket("MS", packet_contents));
}
@@ -1468,7 +1491,10 @@ void Courtroom::handle_chatmessage_2()
qDebug() << "W: invalid emote mod: " << QString::number(emote_mod);
//intentional fallthru
case 0: case 5:
- handle_chatmessage_3();
+ if (m_chatmessage[NONINTERRUPTING_PRE].isEmpty())
+ handle_chatmessage_3();
+ else
+ play_noninterrupting_preanim();
}
}
@@ -1915,8 +1941,45 @@ void Courtroom::play_preanim()
}
+void Courtroom::play_noninterrupting_preanim()
+{
+ QString f_char = m_chatmessage[CHAR_NAME];
+ QString f_preanim = m_chatmessage[PRE_EMOTE];
+
+ //all time values in char.inis are multiplied by a constant(time_mod) to get the actual time
+ int ao2_duration = ao_app->get_ao2_preanim_duration(f_char, f_preanim);
+ int text_delay = ao_app->get_text_delay(f_char, f_preanim) * time_mod;
+ int sfx_delay = m_chatmessage[SFX_DELAY].toInt() * 60;
+
+ int preanim_duration;
+
+ if (ao2_duration < 0)
+ preanim_duration = ao_app->get_preanim_duration(f_char, f_preanim);
+ else
+ preanim_duration = ao2_duration;
+
+ sfx_delay_timer->start(sfx_delay);
+
+ if (!file_exists(ao_app->get_character_path(f_char) + f_preanim.toLower() + ".gif") ||
+ preanim_duration < 0)
+ {
+ anim_state = 4;
+ preanim_done();
+ qDebug() << "could not find " + ao_app->get_character_path(f_char) + f_preanim.toLower() + ".gif";
+ return;
+ }
+
+ ui_vp_player_char->play_pre(f_char, f_preanim, preanim_duration);
+ anim_state = 4;
+ if (text_delay >= 0)
+ text_delay_timer->start(text_delay);
+
+ handle_chatmessage_3();
+}
+
void Courtroom::preanim_done()
{
+ anim_state = 1;
handle_chatmessage_3();
}
@@ -1927,13 +1990,14 @@ void Courtroom::realization_done()
void Courtroom::start_chat_ticking()
{
- ui_vp_message->clear();
- set_text_color();
- rainbow_counter = 0;
//we need to ensure that the text isn't already ticking because this function can be called by two logic paths
if (text_state != 0)
return;
+ ui_vp_message->clear();
+ set_text_color();
+ rainbow_counter = 0;
+
if (chatmessage_is_empty)
{
//since the message is empty, it's technically done ticking
@@ -1992,8 +2056,11 @@ void Courtroom::chat_tick()
if (tick_pos >= f_message.size())
{
text_state = 2;
- anim_state = 3;
- ui_vp_player_char->play_idle(m_chatmessage[CHAR_NAME], m_chatmessage[EMOTE]);
+ if (anim_state != 4)
+ {
+ anim_state = 3;
+ ui_vp_player_char->play_idle(m_chatmessage[CHAR_NAME], m_chatmessage[EMOTE]);
+ }
}
else
@@ -2083,7 +2150,7 @@ void Courtroom::chat_tick()
// Here, we check if the entire message is blue.
// If it isn't, we stop talking.
- if (!entire_message_is_blue)
+ if (!entire_message_is_blue and anim_state != 4)
{
QString f_char = m_chatmessage[CHAR_NAME];
QString f_emote = m_chatmessage[EMOTE];
@@ -2107,7 +2174,7 @@ void Courtroom::chat_tick()
// If it isn't, we start talking if we have completely climbed out of inline blues.
if (!entire_message_is_blue)
{
- if (inline_blue_depth == 0)
+ if (inline_blue_depth == 0 and anim_state != 4)
{
QString f_char = m_chatmessage[CHAR_NAME];
QString f_emote = m_chatmessage[EMOTE];
@@ -2566,18 +2633,23 @@ void Courtroom::on_ooc_return_pressed()
}
}
else if (ooc_message.startsWith("/login"))
+ {
ui_guard->show();
+ append_server_chatmessage("CLIENT", "You were granted the Guard button.");
+ }
else if (ooc_message.startsWith("/rainbow") && ao_app->yellow_text_enabled && !rainbow_appended)
{
//ui_text_color->addItem("Rainbow");
ui_ooc_chat_message->clear();
//rainbow_appended = true;
+ append_server_chatmessage("CLIENT", "This does nohing, but there you go.");
return;
}
else if (ooc_message.startsWith("/settings"))
{
ui_ooc_chat_message->clear();
ao_app->call_settings_menu();
+ append_server_chatmessage("CLIENT", "You opened the settings menu.");
return;
}
else if (ooc_message.startsWith("/pair"))
@@ -2590,7 +2662,21 @@ void Courtroom::on_ooc_return_pressed()
if (ok)
{
if (whom > -1)
+ {
other_charid = whom;
+ QString msg = "You will now pair up with ";
+ msg.append(char_list.at(whom).name);
+ msg.append(" if they also choose your character in return.");
+ append_server_chatmessage("CLIENT", msg);
+ }
+ else
+ {
+ append_server_chatmessage("CLIENT", "You are no longer paired with anyone.");
+ }
+ }
+ else
+ {
+ append_server_chatmessage("CLIENT", "Are you sure you typed that well? The char ID could not be recognised.");
}
return;
}
@@ -2604,18 +2690,34 @@ void Courtroom::on_ooc_return_pressed()
if (ok)
{
if (off >= -100 && off <= 100)
+ {
offset_with_pair = off;
+ QString msg = "You have set your offset to ";
+ msg.append(QString::number(off));
+ msg.append("%.");
+ append_server_chatmessage("CLIENT", msg);
+ }
+ else
+ {
+ append_server_chatmessage("CLIENT", "Your offset must be between -100% and 100%!");
+ }
+ }
+ else
+ {
+ append_server_chatmessage("CLIENT", "That offset does not look like one.");
}
return;
}
else if (ooc_message.startsWith("/switch_am"))
{
+ append_server_chatmessage("CLIENT", "You switched your music and area list.");
on_switch_area_music_clicked();
ui_ooc_chat_message->clear();
return;
}
else if (ooc_message.startsWith("/enable_blocks"))
{
+ append_server_chatmessage("CLIENT", "You have forcefully enabled features that the server may not support. You may not be able to talk IC, or worse, because of this.");
ao_app->shownames_enabled = true;
ao_app->charpairs_enabled = true;
ao_app->arup_enabled = true;
@@ -2624,6 +2726,16 @@ void Courtroom::on_ooc_return_pressed()
ui_ooc_chat_message->clear();
return;
}
+ else if (ooc_message.startsWith("/non_int_pre"))
+ {
+ if (ui_pre_non_interrupt->isChecked())
+ append_server_chatmessage("CLIENT", "Your pre-animations interrupt again.");
+ else
+ append_server_chatmessage("CLIENT", "Your pre-animations will not interrupt text.");
+ ui_pre_non_interrupt->setChecked(!ui_pre_non_interrupt->isChecked());
+ ui_ooc_chat_message->clear();
+ return;
+ }
QStringList packet_contents;
packet_contents.append(ui_ooc_chat_name->text());
diff --git a/courtroom.h b/courtroom.h
index 19a19ea9..d15dde0e 100644
--- a/courtroom.h
+++ b/courtroom.h
@@ -184,6 +184,7 @@ public:
void handle_song(QStringList *p_contents);
void play_preanim();
+ void play_noninterrupting_preanim();
//plays the witness testimony or cross examination animation based on argument
void handle_wtce(QString p_wtce, int variant);
@@ -298,7 +299,7 @@ private:
//every time point in char.inis times this equals the final time
const int time_mod = 40;
- static const int chatmessage_size = 22;
+ static const int chatmessage_size = 23;
QString m_chatmessage[chatmessage_size];
bool chatmessage_is_empty = false;
@@ -319,7 +320,7 @@ private:
bool is_muted = false;
- //state of animation, 0 = objecting, 1 = preanim, 2 = talking, 3 = idle
+ //state of animation, 0 = objecting, 1 = preanim, 2 = talking, 3 = idle, 4 = noniterrupting preanim
int anim_state = 3;
//state of text ticking, 0 = not yet ticking, 1 = ticking in progress, 2 = ticking done
@@ -451,6 +452,7 @@ private:
QCheckBox *ui_flip;
QCheckBox *ui_guard;
+ QCheckBox *ui_pre_non_interrupt;
QCheckBox *ui_showname_enable;
AOButton *ui_custom_objection;
diff --git a/datatypes.h b/datatypes.h
index 63ad836a..aaa5de52 100644
--- a/datatypes.h
+++ b/datatypes.h
@@ -99,7 +99,8 @@ enum CHAT_MESSAGE
OTHER_EMOTE,
SELF_OFFSET,
OTHER_OFFSET,
- OTHER_FLIP
+ OTHER_FLIP,
+ NONINTERRUPTING_PRE
};
enum COLOR
diff --git a/server/aoprotocol.py b/server/aoprotocol.py
index d7a2c6c3..d8d91d2c 100644
--- a/server/aoprotocol.py
+++ b/server/aoprotocol.py
@@ -346,6 +346,7 @@ class AOProtocol(asyncio.Protocol):
showname = ""
charid_pair = -1
offset_pair = 0
+ nonint_pre = ''
elif self.validate_net_cmd(args, self.ArgType.STR, self.ArgType.STR_OR_EMPTY, self.ArgType.STR,
self.ArgType.STR,
self.ArgType.STR, self.ArgType.STR, self.ArgType.STR, self.ArgType.INT,
@@ -355,6 +356,7 @@ class AOProtocol(asyncio.Protocol):
msg_type, pre, folder, anim, text, pos, sfx, anim_type, cid, sfx_delay, button, evidence, flip, ding, color, showname = args
charid_pair = -1
offset_pair = 0
+ nonint_pre = ''
if len(showname) > 0 and not self.client.area.showname_changes_allowed:
self.client.send_host_message("Showname changes are forbidden in this area!")
return
@@ -363,8 +365,19 @@ class AOProtocol(asyncio.Protocol):
self.ArgType.STR, self.ArgType.STR, self.ArgType.STR, self.ArgType.INT,
self.ArgType.INT, self.ArgType.INT, self.ArgType.INT, self.ArgType.INT,
self.ArgType.INT, self.ArgType.INT, self.ArgType.INT, self.ArgType.STR_OR_EMPTY, self.ArgType.INT, self.ArgType.INT):
- # 1.4.0 validation monstrosity.
+ # 1.3.5 validation monstrosity.
msg_type, pre, folder, anim, text, pos, sfx, anim_type, cid, sfx_delay, button, evidence, flip, ding, color, showname, charid_pair, offset_pair = args
+ nonint_pre = ''
+ if len(showname) > 0 and not self.client.area.showname_changes_allowed:
+ self.client.send_host_message("Showname changes are forbidden in this area!")
+ return
+ elif self.validate_net_cmd(args, self.ArgType.STR, self.ArgType.STR_OR_EMPTY, self.ArgType.STR,
+ self.ArgType.STR,
+ self.ArgType.STR, self.ArgType.STR, self.ArgType.STR, self.ArgType.INT,
+ self.ArgType.INT, self.ArgType.INT, self.ArgType.INT, self.ArgType.INT,
+ self.ArgType.INT, self.ArgType.INT, self.ArgType.INT, self.ArgType.STR_OR_EMPTY, self.ArgType.INT, self.ArgType.INT, self.ArgType.INT):
+ # 1.4.0 validation monstrosity.
+ msg_type, pre, folder, anim, text, pos, sfx, anim_type, cid, sfx_delay, button, evidence, flip, ding, color, showname, charid_pair, offset_pair, nonint_pre = args
if len(showname) > 0 and not self.client.area.showname_changes_allowed:
self.client.send_host_message("Showname changes are forbidden in this area!")
return
@@ -383,7 +396,7 @@ class AOProtocol(asyncio.Protocol):
if text.isspace():
self.client.send_host_message("Blankposting is forbidden in this area, and putting more spaces in does not make it not blankposting.")
return
- if len(text.replace(' ', '')) < 3 and text != '<' and text != '>':
+ if len(re.sub(r'[{}\\`|]','', text).replace(' ', '')) < 3 and text != '<' and text != '>':
self.client.send_host_message("While that is not a blankpost, it is still pretty spammy. Try forming sentences.")
return
if msg_type not in ('chat', '0', '1'):
@@ -405,6 +418,13 @@ class AOProtocol(asyncio.Protocol):
if len(showname) > 15:
self.client.send_host_message("Your IC showname is way too long!")
return
+ if self.client.area.non_int_pres_only:
+ if anim_type == 1 or anim_type == 2:
+ anim_type = 0
+ nonint_pre = 1
+ elif anim_type == 6:
+ anim_type = 5
+ nonint_pre = 1
if not self.client.area.shouts_allowed:
# Old clients communicate the objecting in anim_type.
if anim_type == 2:
@@ -471,7 +491,7 @@ class AOProtocol(asyncio.Protocol):
self.client.area.send_command('MS', msg_type, pre, folder, anim, msg, pos, sfx, anim_type, cid,
sfx_delay, button, self.client.evi_list[evidence], flip, ding, color, showname,
- charid_pair, other_folder, other_emote, offset_pair, other_offset, other_flip)
+ charid_pair, other_folder, other_emote, offset_pair, other_offset, other_flip, nonint_pre)
self.client.area.set_next_msg_delay(len(msg))
logger.log_server('[IC][{}][{}]{}'.format(self.client.area.abbreviation, self.client.get_char_name(), msg), self.client)
diff --git a/server/area_manager.py b/server/area_manager.py
index 6e024f6d..23c43397 100644
--- a/server/area_manager.py
+++ b/server/area_manager.py
@@ -26,7 +26,7 @@ from server.evidence import EvidenceList
class AreaManager:
class Area:
- def __init__(self, area_id, server, name, background, bg_lock, evidence_mod = 'FFA', locking_allowed = False, iniswap_allowed = True, showname_changes_allowed = False, shouts_allowed = True, jukebox = False, abbreviation = ''):
+ def __init__(self, area_id, server, name, background, bg_lock, evidence_mod = 'FFA', locking_allowed = False, iniswap_allowed = True, showname_changes_allowed = False, shouts_allowed = True, jukebox = False, abbreviation = '', non_int_pres_only = False):
self.iniswap_allowed = iniswap_allowed
self.clients = set()
self.invite_list = {}
@@ -65,6 +65,7 @@ class AreaManager:
self.is_locked = False
self.blankposting_allowed = True
+ self.non_int_pres_only = non_int_pres_only
self.jukebox = jukebox
self.jukebox_votes = []
self.jukebox_prev_char_id = -1
@@ -305,10 +306,12 @@ class AreaManager:
item['shouts_allowed'] = True
if 'jukebox' not in item:
item['jukebox'] = False
+ if 'noninterrupting_pres' not in item:
+ item['noninterrupting_pres'] = False
if 'abbreviation' not in item:
item['abbreviation'] = self.get_generated_abbreviation(item['area'])
self.areas.append(
- self.Area(self.cur_id, self.server, item['area'], item['background'], item['bglock'], item['evidence_mod'], item['locking_allowed'], item['iniswap_allowed'], item['showname_changes_allowed'], item['shouts_allowed'], item['jukebox'], item['abbreviation']))
+ self.Area(self.cur_id, self.server, item['area'], item['background'], item['bglock'], item['evidence_mod'], item['locking_allowed'], item['iniswap_allowed'], item['showname_changes_allowed'], item['shouts_allowed'], item['jukebox'], item['abbreviation'], item['noninterrupting_pres']))
self.cur_id += 1
def default_area(self):