--- deliantra/Deliantra-Client/bin/pclient 2006/04/24 02:41:48 1.169 +++ deliantra/Deliantra-Client/bin/pclient 2006/04/24 06:57:39 1.175 @@ -49,6 +49,7 @@ our $CONSOLE; our $METASERVER; +our $FLOORBOX; our $GAUGES; our $STATWIDS; @@ -310,19 +311,35 @@ my $win = new CFClient::UI::Frame ( y => $HEIGHT - $gh, x => 0, user_w => $WIDTH, user_h => $gh ); - $win->add (my $vb = new CFClient::UI::VBox); - - $vb->add (my $hbg = new CFClient::UI::HBox expand => 1); - - $hbg->add (new CFClient::UI::Empty expand => 1); - $hbg->add (my $hb = new CFClient::UI::HBox); - $hb->add (my $hg = new CFClient::UI::Gauge type => 'hp', tooltip => "Health points"); - $hb->add (my $mg = new CFClient::UI::Gauge type => 'mana', tooltip => "Spellpoints"); - $hb->add (my $gg = new CFClient::UI::Gauge type => 'grace', tooltip => "Grace"); - $hb->add (my $fg = new CFClient::UI::Gauge type => 'food', tooltip => "Food"); - - $vb->add (my $exp = new CFClient::UI::Label valign => 0, align => 1, text => "XP: 0 LVL: 0"); - $vb->add (my $rng = new CFClient::UI::Label valign => 0, align => 1, text => "Rng:"); + $win->add (my $hbox = new CFClient::UI::HBox + children => [ + (new CFClient::UI::HBox expand => 1), + ($FLOORBOX = new CFClient::UI::VBox), + (my $vbox = new CFClient::UI::VBox), + ], + ); + + $vbox->add (new CFClient::UI::HBox + expand => 1, + children => [ + (new CFClient::UI::Empty expand => 1), + (my $hb = new CFClient::UI::HBox), + ], + ); + + $hb->add (my $hg = new CFClient::UI::Gauge type => 'hp', + tooltip => "Health points - depletes when you get wounded, refills when you heal or idle"); + $hb->add (my $mg = new CFClient::UI::Gauge type => 'mana', + tooltip => "Spell points - deplete when you cast wizard spells, refills when you idle"); + $hb->add (my $gg = new CFClient::UI::Gauge type => 'grace', + tooltip => "Grace points - deplete when you cast priest spells, refills when you pray"); + $hb->add (my $fg = new CFClient::UI::Gauge type => 'food', + tooltip => "Food - depletes with time, faster when you heal or build mana, refills when you eat healthy food"); + + $vbox->add (my $exp = new CFClient::UI::Label valign => 0, align => 1, can_hover => 1, can_events => 1, + tooltip => "Experience points and level - increases when you kill monsters or successfully use skills"); + $vbox->add (my $rng = new CFClient::UI::Label valign => 0, align => 1, can_hover => 1, can_events => 1, + tooltip => "Ranged attack - how you attack when you press shift-cursor (spell, skill, weapon etc.)"); $GAUGES = { exp => $exp, win => $win, range => $rng, @@ -345,6 +362,8 @@ $hb->add (my $tbl = new CFClient::UI::Table expand => 1); + my $black = [0, 0, 0]; + $tbl->add (0, 0, $STATWIDS->{st_str} = new CFClient::UI::Label valign => 0, align => +1, template => "30"); $tbl->add (0, 1, $STATWIDS->{st_dex} = new CFClient::UI::Label valign => 0, align => +1, template => "30"); $tbl->add (0, 2, $STATWIDS->{st_con} = new CFClient::UI::Label valign => 0, align => +1, template => "30"); @@ -353,13 +372,13 @@ $tbl->add (0, 5, $STATWIDS->{st_pow} = new CFClient::UI::Label valign => 0, align => +1, template => "30"); $tbl->add (0, 6, $STATWIDS->{st_cha} = new CFClient::UI::Label valign => 0, align => +1, template => "30"); - $tbl->add (1, 0, $STATWIDS->{st_str_lbl} = new CFClient::UI::Label valign => 0, align => -1, text => "Str"); - $tbl->add (1, 1, $STATWIDS->{st_dex_lbl} = new CFClient::UI::Label valign => 0, align => -1, text => "Dex"); - $tbl->add (1, 2, $STATWIDS->{st_con_lbl} = new CFClient::UI::Label valign => 0, align => -1, text => "Con"); - $tbl->add (1, 3, $STATWIDS->{st_int_lbl} = new CFClient::UI::Label valign => 0, align => -1, text => "Int"); - $tbl->add (1, 4, $STATWIDS->{st_wis_lbl} = new CFClient::UI::Label valign => 0, align => -1, text => "Wis"); - $tbl->add (1, 5, $STATWIDS->{st_pow_lbl} = new CFClient::UI::Label valign => 0, align => -1, text => "Pow"); - $tbl->add (1, 6, $STATWIDS->{st_cha_lbl} = new CFClient::UI::Label valign => 0, align => -1, text => "Cha"); + $tbl->add (1, 0, $STATWIDS->{st_str_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Str"); + $tbl->add (1, 1, $STATWIDS->{st_dex_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Dex"); + $tbl->add (1, 2, $STATWIDS->{st_con_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Con"); + $tbl->add (1, 3, $STATWIDS->{st_int_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Int"); + $tbl->add (1, 4, $STATWIDS->{st_wis_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Wis"); + $tbl->add (1, 5, $STATWIDS->{st_pow_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Pow"); + $tbl->add (1, 6, $STATWIDS->{st_cha_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Cha"); $tbl->add (2, 0, $STATWIDS->{st_wc} = new CFClient::UI::Label valign => 0, align => +1, template => "-120"); $tbl->add (2, 1, $STATWIDS->{st_ac} = new CFClient::UI::Label valign => 0, align => +1, template => "-120"); @@ -368,12 +387,12 @@ $tbl->add (2, 4, $STATWIDS->{st_spd} = new CFClient::UI::Label valign => 0, align => +1, template => "10.54"); $tbl->add (2, 5, $STATWIDS->{st_wspd} = new CFClient::UI::Label valign => 0, align => +1, template => "9"); - $tbl->add (3, 0, $STATWIDS->{st_wc_lbl} = new CFClient::UI::Label valign => 0, align => -1, text => "Wc"); - $tbl->add (3, 1, $STATWIDS->{st_ac_lbl} = new CFClient::UI::Label valign => 0, align => -1, text => "Ac"); - $tbl->add (3, 2, $STATWIDS->{st_dam_lbl} = new CFClient::UI::Label valign => 0, align => -1, text => "Dam"); - $tbl->add (3, 3, $STATWIDS->{st_arm_lbl} = new CFClient::UI::Label valign => 0, align => -1, text => "Arm"); - $tbl->add (3, 4, $STATWIDS->{st_spd_lbl} = new CFClient::UI::Label valign => 0, align => -1, text => "Sp"); - $tbl->add (3, 5, $STATWIDS->{st_wspd_lbl} = new CFClient::UI::Label valign => 0, align => -1, text => "WSp"); + $tbl->add (3, 0, $STATWIDS->{st_wc_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Wc"); + $tbl->add (3, 1, $STATWIDS->{st_ac_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Ac"); + $tbl->add (3, 2, $STATWIDS->{st_dam_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Dam"); + $tbl->add (3, 3, $STATWIDS->{st_arm_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Arm"); + $tbl->add (3, 4, $STATWIDS->{st_spd_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "Sp"); + $tbl->add (3, 5, $STATWIDS->{st_wspd_lbl} = new CFClient::UI::Label fg => $black, valign => 0, align => -1, text => "WSp"); $hb->add (my $tbl2 = new CFClient::UI::Table expand => 1); @@ -640,7 +659,7 @@ text => $CFG->{say_command}, tooltip => "This is the command that will be used if you write a line in the message window entry. " ."Usually you want to enter something like 'say' or 'shout' or 'gsay' here. " - ."But you could also set it to 'tell ' to only chat with that user.", + ."But you could also set it to 'tell <playername>' to only chat with that user.", connect_changed => sub { my ($self, $value) = @_; $CFG->{say_command} = $value; @@ -1085,6 +1104,7 @@ gotid: $face->{id} = $id; $MAP->set_face ($facenum => $id); + $self->{faceid}[$facenum] = $id;#d# $TILECACHE->get ($id) } @@ -1102,7 +1122,7 @@ $self->{texture}[$id] ||= do { my $tex = new_from_image CFClient::Texture - $data, minify => 1; + $data, minify => 1, mipmap => 1; $MAP->set_texture ($id, @$tex{qw(name w h s t)}, @{$tex->{minified}}); $MAPWIDGET->update; @@ -1124,11 +1144,71 @@ # warn "sound $x,$y,$soundnum,$type\n";#d# } +my $LAST_QUERY; # server is stupid, stupid, stupid + sub conn::query { my ($self, $flags, $prompt) = @_; - #TODO, display dialog with relevant information - warn "<<<>>\n";#d# + $prompt = $LAST_QUERY unless length $prompt; + $LAST_QUERY = $prompt; + + my $dialog = new CFClient::UI::FancyFrame + title => "Query", + child => my $vbox = new CFClient::UI::VBox; + + $vbox->add (new CFClient::UI::Label + max_w => $::WIDTH * 0.4, + text => $prompt); + + if ($flags & Crossfire::Protocol::CS_QUERY_YESNO) { + $vbox->add (my $hbox = new CFClient::HBox); + $hbox->add (new CFClient::Button + text => "No", + connect_activate => sub { + $self->send ("reply n"); + $dialog->destroy; + $MAPWIDGET->focus_in; + } + ); + $hbox->add (new CFClient::Button + text => "Yes", + connect_activate => sub { + $self->send ("reply y"); + $dialog->destroy; + $MAPWIDGET->focus_in; + }, + ); + + $dialog->focus_in; + + } elsif ($flags & Crossfire::Protocol::CS_QUERY_SINGLECHAR) { + $dialog->{tooltip} = "Press a key (click on the entry to make sure it has keyboard focus)"; + $vbox->add (my $entry = new CFClient::UI::Entry + connect_changed => sub { + $self->send ("reply $_[1]"); + $dialog->destroy; + $MAPWIDGET->focus_in; + }, + ); + + $entry->focus_in; + + } else { + $dialog->{tooltip} = "Enter the reply and press return (click on the entry to make sure it has keyboard focus)"; + + $vbox->add (my $entry = new CFClient::UI::Entry + $flags & Crossfire::Protocol::CS_QUERY_HIDEINPUT ? (hiddenchar => "*") : (), + connect_activate => sub { + $self->send ("reply $_[1]"); + $dialog->destroy; + $MAPWIDGET->focus_in; + }, + ); + + $entry->focus_in; + } + + $dialog->show; } sub conn::drawinfo { @@ -1156,10 +1236,10 @@ sub conn::spell_add { my ($self, $spell) = @_; - $MAPWIDGET->add_command ("invoke $spell->{name}", $spell->{message}, sub { - }); - $MAPWIDGET->add_command ("cast $spell->{name}", $spell->{message}, sub { - }); + # TODO + # create a widget dynamically, using spell face (CF::Protocol downloads them) + $MAPWIDGET->add_command ("invoke $spell->{name}", $spell->{message}); + $MAPWIDGET->add_command ("cast $spell->{name}", $spell->{message}); } sub conn::spell_delete { @@ -1170,26 +1250,93 @@ my ($self) = @_; for my $skill (values %{$self->{skill_info}}) { - $MAPWIDGET->add_command ("ready_skill $skill", "", sub { - }); - $MAPWIDGET->add_command ("use_skill $skill", "", sub { - }); + $MAPWIDGET->add_command ("ready_skill $skill", "Ready the skill '$skill'"); + $MAPWIDGET->add_command ("use_skill $skill", "Immediately use the skill '$skill'"); } } +sub update_floorbox { + $CFClient::UI::ROOT->on_refresh ($FLOORBOX => sub { + $FLOORBOX->clear; + $FLOORBOX->add (new CFClient::UI::Empty expand => 1); + + my @items = values %{ $CONN->{container}{0} }; + + # we basically have to use the same sorting as everybody else + @items = sort { $a->{type} <=> $b->{type} } @items; + + for my $item (reverse @items) { + my $desc = $item->{nrof} < 2 + ? $item->{name} + : "$item->{nrof} $item->{name_pl}"; + # todo: animation widget, face widget, weight(?) etc. + $FLOORBOX->add (my $hbox = new CFClient::UI::HBox + tooltip => (CFClient::UI::Label->escape ($desc) + . "\nleftclick - pick up\nmiddle click - apply\nrightclick - menu"), + can_hover => 1, + can_events => 1, + connect_button_down => sub { + my ($self, $ev, $x, $y) = @_; + + # todo: maybe put examine on 1? but should just be a tooltip :( + if ($ev->{button} == 1) { + $CONN->send ("move $CONN->{player}{tag} $item->{tag} 0"); + } elsif ($ev->{button} == 2) { + $CONN->send ("apply $item->{tag}"); + } elsif ($ev->{button} == 3) { + # examine, lock, mark, maybe other things + warn "MENU not implemented yet\n"; + } + + 1 + }, + ); + + $hbox->add (new CFClient::UI::Face + can_events => 0, + face => $item->{face}, + anim => $item->{anim}, + animspeed => $item->{animspeed}, + ); + + $hbox->add (new CFClient::UI::Label + can_events => 0, + text => $desc, + ); + } + }); + refresh; +} + sub conn::container_add { my ($self, $id, $items) = @_; - # 0 floor + update_floorbox if $id == 0; # $self-<{player}{tag} => player inv #use PApp::Util; warn PApp::Util::dumpval $self->{container}{$self->{player}{tag}}; } sub conn::container_clear { my ($self, $id) = @_; + + update_floorbox if $id == 0; # use PApp::Util; warn PApp::Util::dumpval $self->{container}{0}; } +sub conn::item_delete { + my ($self, @items) = @_; + + for (@items) { + update_floorbox if $_->{container} == 0; + } +} + +sub conn::item_update { + my ($self, $item) = @_; + + update_floorbox if $item->{container} == 0; +} + %SDL_CB = ( CFClient::SDL_QUIT => sub { Event::unloop -1;