Games-Construder
view release on metacpan or search on metacpan
lib/Games/Construder/Server/Player.pm view on Meta::CPAN
if ($ov) {
$self->{uis}->{status}->show ([@$item]);
$self->refill_bio ($item->[1]);
return 1;
}
}
} else {
my ($ov) = $self->{inv}->remove ($item->[0]);
if ($ov) {
$self->{uis}->{status}->show ([@$item]);
$self->refill_bio ($item->[1]);
return 1;
}
}
return 0;
}
sub refill_bio {
my ($self, $amount) = @_;
$self->{data}->{bio} += $amount;
$self->{data}->{bio} = 100
if $self->{data}->{bio} > 100;
if ($self->{data}->{bio} > 0) {
$self->starvation (0); # make sure we don't starve anymore
}
}
sub kill_player {
my ($self, $reason) = @_;
my $pp = $self->{data}->{pos};
my ($new_pos, $dist, $secdist) = world_find_random_teleport_destination_at_dist ($pp, 780);
$self->teleport ($new_pos);
$self->msg (1, "You died of $reason, your stats and inventory were reset and you have been teleported $secdist sectors away!");
$self->{inv}->remove ('all');
my $inv = $Games::Construder::Server::RES->get_initial_inventory;
$self->{data}->{inv}->{$_} = $inv->{$_} for keys %$inv;
$self->{data}->{happyness} = 100;
$self->{data}->{bio} = 100;
$self->{data}->{score} = 0;
$self->update_score;
}
sub logout {
my ($self) = @_;
$self->save;
delete $self->{uis};
delete $self->{upd_score_hl_tmout};
delete $self->{death_timer};
delete $self->{tick_timer};
ctr_log (info => "Player %s logged out", $self->{name});
#d# print Devel::FindRef::track $self;
}
my $world_c = 0;
sub update_pos {
my ($self, $pos, $lv) = @_;
if ($self->{freeze_update_pos} ne '') {
ctr_log (debug => "update_pos thrown away, awaiting teleport confirmation!");
return;
}
my $opos = $self->{data}->{pos};
$self->{data}->{pos} = $pos;
my $olv = $self->{data}->{look_vec} || [0,0,0];
$self->{data}->{look_vec} = vnorm ($lv);
my $oblk = vfloor ($opos);
my $nblk = vfloor ($pos);
my $new_pos = vlength (vsub ($oblk, $nblk)) > 0;
my $new_lv = vlength (vsub ($olv, $lv)) > 0.05;
my $dnew_lv = vlength (vsub ($olv, $lv));
if ($new_pos || $new_lv) {
if ($self->{uis}->{navigator}->{shown}) {
$self->{uis}->{navigator}->show;
}
}
return unless $new_pos;
$self->upd_visible_chunks;
}
sub upd_visible_chunks {
my ($self) = @_;
$self->calc_visible_sectors;
world_load_at_player ($self, sub { });
}
sub get_pos_normalized {
my ($self) = @_;
vfloor ($self->{data}->{pos})
}
sub get_pos_chnk {
my ($self) = @_;
world_pos2chnkpos ($self->{data}->{pos})
}
sub get_pos_sector {
my ($self) = @_;
world_chnkpos2secpos (world_pos2chnkpos ($self->{data}->{pos}))
}
sub set_vis_rad {
my ($self, $rad) = @_;
$self->{vis_rad} = $rad || $PL_VIS_RAD;
}
sub set_visible_chunks {
my ($self, $new, $old, $req) = @_;
for (@$old) {
lib/Games/Construder/Server/Player.pm view on Meta::CPAN
delete $self->{sent_chunks}->{$id};
}
}
#delete $self->{chunk_uptodate}->{world_pos2id ($chnk)};
}
sub push_chunk_to_network {
my ($self) = @_;
my (@upds) = values %{$self->{to_send_chunks}};
my $plpos = $self->{data}->{pos};
my $plchnk = world_pos2chnkpos ($self->{data}->{pos});
(@upds) = grep {
$self->{visible_chunk_ids}->{world_pos2id ($_)}
} @upds;
(@upds) = sort {
vlength (vsub ($plchnk, $a))
<=>
vlength (vsub ($plchnk, $b))
} @upds;
splice @upds, $PL_MAX_QUEUE_SIZE;
my $cnt = scalar @upds;
ctr_log (debug => "player %s: %d chunk updates in queue", $self->{name}, $cnt)
if $cnt;
for (my $i = 0; $i < 5; $i++) {
my $q = shift @upds
or return;
$self->send_chunk ($q);
}
}
sub send_chunk {
my ($self, $chnk) = @_;
# only send chunk when allcoated, in all other cases the chunk will
# be sent by the chunk_changed-callback by the server (when it checks
# whether any player might be interested in that chunk).
my $id = world_pos2id ($chnk);
my $data = Games::Construder::World::get_chunk_data (@$chnk);
unless (defined $data) {
#d# warn "send_chunk: @$chnk was not yet allocated!\n";
delete $self->{to_send_chunks}->{$id};
return;
}
my $buf = compress ($data);
$self->send_client ({ cmd => "chunk", pos => $chnk }, \$buf);
$self->{sent_chunks}->{$id} = $chnk;
delete $self->{to_send_chunks}->{$id};
}
sub msg {
my ($self, $error, $msg) = @_;
$self->{uis}->{msgbox}->show ($error, $msg);
}
sub update_score {
my ($self, $hl) = @_;
$self->{uis}->{score}->show ($hl);
}
sub query {
my ($self, $pos) = @_;
return unless @$pos;
world_mutate_at ($pos, sub {
my ($data) = @_;
if ($data->[0]) {
$self->{uis}->{material_view}->show ($data->[0], $data->[5]);
}
return 0;
}, need_entity => 1);
}
sub interact {
my ($self, $pos) = @_;
world_at ($pos, sub {
my ($pos, $cell) = @_;
Games::Construder::Server::Objects::interact ($self, $pos, $cell->[0], $cell->[5]);
});
}
sub highlight {
my ($self, $pos, $time, $color) = @_;
$self->send_client ({
cmd => "highlight",
pos => $pos,
color => $color,
fade => -$time
});
}
sub debug_at {
my ($self, $pos) = @_;
$self->send_client ({
cmd => "model_highlight",
pos => $pos,
model => [
map {
my $x = $_;
map {
my $y = $_;
map { [[$x, $y, $_], [1, 0, rand (100) / 100, 0.2]] } 0..10
} 0..10
} 0..10
],
id => "debug"
});
world_mutate_at ($pos, sub {
my ($data) = @_;
ctr_log (debug => "player %s: debug position @$pos: @$data", $self->{name});
if ($data->[0] == 1) {
$data->[0] = 0;
return 1;
}
return 0;
lib/Games/Construder/Server/Player.pm view on Meta::CPAN
my ($self) = @_;
my $t = time;
my $assign = $self->{data}->{assignment};
my $lpos = { %{$assign->{pos_types}} };
my $typ =
Games::Construder::World::get_types_in_cube (@{$assign->{pos}}, $assign->{size});
#d#printf "CHECK TIME 1 %f\n", time - $t;
for (my $x = 0; $x < $assign->{size}; $x++) {
for (my $y = 0; $y < $assign->{size}; $y++) {
for (my $z = 0; $z < $assign->{size}; $z++) {
my $t = shift @$typ;
my $pid = join (",", @{vaddd ($assign->{pos}, $x, $y, $z)});
if ($assign->{pos_types}->{$pid}) {
if ($assign->{pos_types}->{$pid} == $t) {
delete $lpos->{$pid};
}
}
}
}
}
my %tleft;
for (keys %$lpos) {
$tleft{$lpos->{$_}}++;
}
$assign->{left} = \%tleft;
#d#printf "CHECK TIME 2 %f\n", time - $t;
$self->update_assignment_highlight;
unless (grep { $_ != 0 } values %tleft) {
$self->finished_assignmenet;
}
}
sub assignment_select_next {
my ($self) = @_;
my $assign = $self->{data}->{assignment};
my @left = grep {
$assign->{left}->{$_} > 0
} keys %{$assign->{left}};
push @left, @left;
for (my $i = 0; $i < (@left / 2); $i++) {
if ($left[$i] == $assign->{sel_mat}) {
$assign->{sel_mat} = $left[$i + 1];
last;
}
}
delete $self->{assign_ment_hl};
$self->update_assignment_highlight;
$self->{uis}->{assignment_time}->show;
}
sub update_assignment_highlight {
my ($self) = @_;
my $assign = $self->{data}->{assignment};
my $selected = $assign->{sel_mat};
if ($assign->{left}->{$selected} <= 0) {
($assign->{sel_mat}) = grep {
$assign->{left}->{$_} > 0
} keys %{$assign->{left}};
delete $self->{assign_ment_hl};
}
unless ($self->{assign_ment_hl}) {
$self->{assign_ment_hl} = 1;
my $mat = $assign->{sel_mat};
$self->send_client ({
cmd => "model_highlight",
pos => $assign->{pos},
model => $assign->{mat_models}->{$mat},
id => "assignment",
});
}
}
sub check_assignment {
my ($self) = @_;
my $assign = $self->{data}->{assignment};
unless ($assign) {
$self->{uis}->{assignment_time}->hide;
$self->send_client ({
cmd => "model_highlight",
id => "assignment"
});
return;
}
$self->check_assignment_positions;
# was it finished?!
return unless $self->{data}->{assignment};
$self->{uis}->{assignment_time}->show;
my $wself = $self;
weaken $wself;
$self->{assign_timer} = AE::timer 1, 1, sub {
$wself->check_assignment_positions;
# was it finished?!
return unless $self->{data}->{assignment};
$wself->{data}->{assignment}->{time} -= 1;
$wself->{uis}->{assignment_time}->show;
if ($wself->{data}->{assignment}->{time} <= 0) {
$wself->cancel_assignment;
}
};
}
sub finished_assignmenet {
my ($self) = @_;
my $score = $self->{data}->{assignment}->{score};
( run in 1.372 second using v1.01-cache-2.11-cpan-39bf76dae61 )