Dual characters on screen Part I

The basics have been laid out.
- Communication about the second character established.
- Pairing sytem made.
- Placement system of the second character implemented.

Needs:
- More testing.
- A workable UI.
- Fix for zooms.
This commit is contained in:
Cerapter 2018-09-03 03:52:16 +02:00
parent 00bfa025a2
commit 739142f8dd
5 changed files with 228 additions and 9 deletions

View File

@ -80,6 +80,8 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_vp_speedlines = new AOMovie(ui_viewport, ao_app); ui_vp_speedlines = new AOMovie(ui_viewport, ao_app);
ui_vp_speedlines->set_play_once(false); ui_vp_speedlines->set_play_once(false);
ui_vp_player_char = new AOCharMovie(ui_viewport, ao_app); ui_vp_player_char = new AOCharMovie(ui_viewport, ao_app);
ui_vp_sideplayer_char = new AOCharMovie(ui_viewport, ao_app);
ui_vp_sideplayer_char->hide();
ui_vp_desk = new AOScene(ui_viewport, ao_app); ui_vp_desk = new AOScene(ui_viewport, ao_app);
ui_vp_legacy_desk = new AOScene(ui_viewport, ao_app); ui_vp_legacy_desk = new AOScene(ui_viewport, ao_app);
@ -379,6 +381,9 @@ void Courtroom::set_widgets()
ui_vp_player_char->move(0, 0); ui_vp_player_char->move(0, 0);
ui_vp_player_char->combo_resize(ui_viewport->width(), ui_viewport->height()); ui_vp_player_char->combo_resize(ui_viewport->width(), ui_viewport->height());
ui_vp_sideplayer_char->move(0, 0);
ui_vp_sideplayer_char->combo_resize(ui_viewport->width(), ui_viewport->height());
//the AO2 desk element //the AO2 desk element
ui_vp_desk->move(0, 0); ui_vp_desk->move(0, 0);
ui_vp_desk->resize(ui_viewport->width(), ui_viewport->height()); ui_vp_desk->resize(ui_viewport->width(), ui_viewport->height());
@ -891,6 +896,12 @@ void Courtroom::on_chat_return_pressed()
//realization# //realization#
//text_color#% //text_color#%
// Additionally, in our case:
//showname#
//other_charid#
//self_offset#%
QStringList packet_contents; QStringList packet_contents;
QString f_side = ao_app->get_char_side(current_char); QString f_side = ao_app->get_char_side(current_char);
@ -997,6 +1008,19 @@ void Courtroom::on_chat_return_pressed()
packet_contents.append(ui_ic_chat_name->text()); packet_contents.append(ui_ic_chat_name->text());
} }
// If there is someone this user would like to appear with.
if (other_charid > -1)
{
// First, we'll add a filler in case we haven't set an IC showname.
if (ui_ic_chat_name->text().isEmpty())
{
packet_contents.append("");
}
packet_contents.append(QString::number(other_charid));
packet_contents.append(QString::number(offset_with_pair));
}
ao_app->send_server_packet(new AOPacket("MS", packet_contents)); ao_app->send_server_packet(new AOPacket("MS", packet_contents));
} }
@ -1184,6 +1208,125 @@ void Courtroom::handle_chatmessage_2()
else else
ui_vp_player_char->set_flipped(false); ui_vp_player_char->set_flipped(false);
QString side = m_chatmessage[SIDE];
// Making the second character appear.
if (m_chatmessage[OTHER_CHARID].isEmpty())
{
// If there is no second character, hide 'em, and center the first.
ui_vp_sideplayer_char->hide();
ui_vp_sideplayer_char->move(0,0);
ui_vp_player_char->move(0,0);
}
else
{
bool ok;
int got_other_charid = m_chatmessage[OTHER_CHARID].toInt(&ok);
if (ok)
{
if (got_other_charid > -1)
{
// If there is, show them!
ui_vp_sideplayer_char->show();
// Depending on where we are, we offset the characters, and reorder their stacking.
if (side == "def")
{
// We also move the character down depending on how far the are to the right.
int hor_offset = m_chatmessage[SELF_OFFSET].toInt();
int vert_offset = 0;
if (hor_offset > 0)
{
vert_offset = hor_offset / 20;
}
ui_vp_player_char->move(ui_viewport->width() * hor_offset / 100, ui_viewport->height() * vert_offset / 100);
// We do the same with the second character.
int hor2_offset = m_chatmessage[OTHER_OFFSET].toInt();
int vert2_offset = 0;
if (hor2_offset > 0)
{
vert2_offset = hor2_offset / 20;
}
ui_vp_sideplayer_char->move(ui_viewport->width() * hor2_offset / 100, ui_viewport->height() * vert2_offset / 100);
// Finally, we reorder them based on who is more to the left.
// The person more to the left is more in the front.
if (hor2_offset >= hor_offset)
{
ui_vp_sideplayer_char->raise();
ui_vp_player_char->raise();
}
else
{
ui_vp_player_char->raise();
ui_vp_sideplayer_char->raise();
}
ui_vp_desk->raise();
ui_vp_legacy_desk->raise();
}
else if (side == "pro")
{
// Almost the same thing happens here, but in reverse.
int hor_offset = m_chatmessage[SELF_OFFSET].toInt();
int vert_offset = 0;
if (hor_offset < 0)
{
// We don't want to RAISE the char off the floor.
vert_offset = -1 * hor_offset / 20;
}
ui_vp_player_char->move(ui_viewport->width() * hor_offset / 100, ui_viewport->height() * vert_offset / 100);
// We do the same with the second character.
int hor2_offset = m_chatmessage[OTHER_OFFSET].toInt();
int vert2_offset = 0;
if (hor2_offset < 0)
{
vert2_offset = -1 * hor2_offset / 20;
}
ui_vp_sideplayer_char->move(ui_viewport->width() * hor2_offset, ui_viewport->height() * vert2_offset);
// Finally, we reorder them based on who is more to the right.
if (hor2_offset <= hor_offset)
{
ui_vp_sideplayer_char->raise();
ui_vp_player_char->raise();
}
else
{
ui_vp_player_char->raise();
ui_vp_sideplayer_char->raise();
}
ui_vp_desk->raise();
ui_vp_legacy_desk->raise();
}
else
{
// In every other case, the talker is on top.
ui_vp_sideplayer_char->raise();
ui_vp_player_char->raise();
ui_vp_desk->raise();
ui_vp_legacy_desk->raise();
}
// We should probably also play the other character's idle emote.
if (ao_app->flipping_enabled && m_chatmessage[OTHER_FLIP].toInt() == 1)
ui_vp_sideplayer_char->set_flipped(true);
else
ui_vp_sideplayer_char->set_flipped(false);
ui_vp_sideplayer_char->play_idle(char_list.at(got_other_charid).name, m_chatmessage[OTHER_EMOTE]);
}
else
{
// If the server understands other characters, but there
// really is no second character, hide 'em, and center the first.
ui_vp_sideplayer_char->hide();
ui_vp_sideplayer_char->move(0,0);
ui_vp_player_char->move(0,0);
}
}
}
switch (emote_mod) switch (emote_mod)
{ {
@ -1216,10 +1359,11 @@ void Courtroom::handle_chatmessage_3()
int emote_mod = m_chatmessage[EMOTE_MOD].toInt(); int emote_mod = m_chatmessage[EMOTE_MOD].toInt();
QString side = m_chatmessage[SIDE];
if (emote_mod == 5 || if (emote_mod == 5 ||
emote_mod == 6) emote_mod == 6)
{ {
QString side = m_chatmessage[SIDE];
ui_vp_desk->hide(); ui_vp_desk->hide();
ui_vp_legacy_desk->hide(); ui_vp_legacy_desk->hide();
@ -2309,6 +2453,34 @@ void Courtroom::on_ooc_return_pressed()
ao_app->call_settings_menu(); ao_app->call_settings_menu();
return; return;
} }
else if (ooc_message.startsWith("/pair"))
{
ui_ooc_chat_message->clear();
ooc_message.remove(0,6);
bool ok;
int whom = ooc_message.toInt(&ok);
if (ok)
{
if (whom > -1)
other_charid = whom;
}
return;
}
else if (ooc_message.startsWith("/offset"))
{
ui_ooc_chat_message->clear();
ooc_message.remove(0,8);
bool ok;
int off = ooc_message.toInt(&ok);
if (ok)
{
if (off >= -100 && off <= 100)
offset_with_pair = off;
}
return;
}
QStringList packet_contents; QStringList packet_contents;
packet_contents.append(ui_ooc_chat_name->text()); packet_contents.append(ui_ooc_chat_name->text());

View File

@ -194,6 +194,12 @@ private:
// in inline blues. // in inline blues.
int inline_blue_depth = 0; int inline_blue_depth = 0;
// The character ID of the character this user wants to appear alongside with.
int other_charid = -1;
// The offset this user has given if they want to appear alongside someone.
int offset_with_pair = 0;
QVector<char_type> char_list; QVector<char_type> char_list;
QVector<evi_type> evidence_list; QVector<evi_type> evidence_list;
QVector<QString> music_list; QVector<QString> music_list;
@ -240,7 +246,7 @@ private:
//every time point in char.inis times this equals the final time //every time point in char.inis times this equals the final time
const int time_mod = 40; const int time_mod = 40;
static const int chatmessage_size = 16; static const int chatmessage_size = 21;
QString m_chatmessage[chatmessage_size]; QString m_chatmessage[chatmessage_size];
bool chatmessage_is_empty = false; bool chatmessage_is_empty = false;
@ -323,6 +329,7 @@ private:
AOScene *ui_vp_background; AOScene *ui_vp_background;
AOMovie *ui_vp_speedlines; AOMovie *ui_vp_speedlines;
AOCharMovie *ui_vp_player_char; AOCharMovie *ui_vp_player_char;
AOCharMovie *ui_vp_sideplayer_char;
AOScene *ui_vp_desk; AOScene *ui_vp_desk;
AOScene *ui_vp_legacy_desk; AOScene *ui_vp_legacy_desk;
AOEvidenceDisplay *ui_vp_evidence_display; AOEvidenceDisplay *ui_vp_evidence_display;

View File

@ -93,7 +93,12 @@ enum CHAT_MESSAGE
FLIP, FLIP,
REALIZATION, REALIZATION,
TEXT_COLOR, TEXT_COLOR,
SHOWNAME SHOWNAME,
OTHER_CHARID,
OTHER_EMOTE,
SELF_OFFSET,
OTHER_OFFSET,
OTHER_FLIP
}; };
enum COLOR enum COLOR

View File

@ -342,12 +342,14 @@ class AOProtocol(asyncio.Protocol):
self.ArgType.INT, self.ArgType.INT, self.ArgType.INT): self.ArgType.INT, self.ArgType.INT, self.ArgType.INT):
msg_type, pre, folder, anim, text, pos, sfx, anim_type, cid, sfx_delay, button, evidence, flip, ding, color = args msg_type, pre, folder, anim, text, pos, sfx, anim_type, cid, sfx_delay, button, evidence, flip, ding, color = args
showname = "" showname = ""
charid_pair = -1
offset_pair = 0
elif self.validate_net_cmd(args, self.ArgType.STR, self.ArgType.STR_OR_EMPTY, self.ArgType.STR, 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.STR, self.ArgType.INT, 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.INT,
self.ArgType.INT, self.ArgType.INT, self.ArgType.INT, self.ArgType.STR): self.ArgType.INT, self.ArgType.INT, self.ArgType.INT, self.ArgType.STR_OR_EMPTY, self.ArgType.INT, self.ArgType.INT):
msg_type, pre, folder, anim, text, pos, sfx, anim_type, cid, sfx_delay, button, evidence, flip, ding, color, showname = args msg_type, pre, folder, anim, text, pos, sfx, anim_type, cid, sfx_delay, button, evidence, flip, ding, color, showname, charid_pair, offset_pair = args
if len(showname) > 0 and not self.client.area.showname_changes_allowed: if len(showname) > 0 and not self.client.area.showname_changes_allowed:
self.client.send_host_message("Showname changes are forbidden in this area!") self.client.send_host_message("Showname changes are forbidden in this area!")
return return
@ -412,8 +414,35 @@ class AOProtocol(asyncio.Protocol):
if self.client.area.evi_list.evidences[self.client.evi_list[evidence] - 1].pos != 'all': if self.client.area.evi_list.evidences[self.client.evi_list[evidence] - 1].pos != 'all':
self.client.area.evi_list.evidences[self.client.evi_list[evidence] - 1].pos = 'all' self.client.area.evi_list.evidences[self.client.evi_list[evidence] - 1].pos = 'all'
self.client.area.broadcast_evidence_list() self.client.area.broadcast_evidence_list()
# Here, we check the pair stuff, and save info about it to the client.
# Notably, while we only get a charid_pair and an offset, we send back a chair_pair, an emote, a talker offset
# and an other offset.
self.client.charid_pair = charid_pair
self.client.offset_pair = offset_pair
self.client.last_sprite = anim
self.client.flip = flip
other_offset = 0
other_emote = ''
other_flip = 0
confirmed = False
if charid_pair > -1:
for target in self.client.area.clients:
if target.char_id == self.client.charid_pair and target.charid_pair == self.client.char_id and target != self.client and target.pos == self.client.pos:
confirmed = True
other_offset = target.offset_pair
other_emote = target.last_sprite
other_flip = target.flip
break
if not confirmed:
charid_pair = -1
offset_pair = 0
self.client.area.send_command('MS', msg_type, pre, folder, anim, msg, pos, sfx, anim_type, cid, 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) sfx_delay, button, self.client.evi_list[evidence], flip, ding, color, showname,
charid_pair, other_emote, offset_pair, other_offset, other_flip)
self.client.area.set_next_msg_delay(len(msg)) 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) logger.log_server('[IC][{}][{}]{}'.format(self.client.area.abbreviation, self.client.get_char_name(), msg), self.client)

View File

@ -58,6 +58,12 @@ class ClientManager:
self.ipid = ipid self.ipid = ipid
self.websocket = None self.websocket = None
# Pairing stuff
self.charid_pair = -1
self.offset_pair = 0
self.last_sprite = ''
self.flip = 0
#flood-guard stuff #flood-guard stuff
self.mus_counter = 0 self.mus_counter = 0
self.mus_mute_time = 0 self.mus_mute_time = 0