2 ##########################################################################
4 # Copyright (c) 2003-2012 Aymargeddon Development Team
6 # This file is part of "Last days of Aymargeddon" - a massive multi player
7 # onine game of strategy
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU Affero General Public License as
11 # published by the Free Software Foundation, either version 3 of the
12 # License, or (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 # See the GNU Affero General Public License for more details.
20 # You should have received a copy of the GNU Affero General Public License
21 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 ###########################################################################
26 # generell Game-specific functions
37 my ($class,$game,$user,$db) = @_;
41 # create database-object, if not given with call
45 $self->{-db} = DataBase->new();
47 # $db->set_language($lang);
49 $self->{-game} = $game;
50 $self->{-user} = $user;
56 my ($self,$cmd,$args,$loc,$player,$exec) = @_;
57 $player = $self->{-user} unless defined $player;
58 my $db = $self->{-db};
60 my ($now) = $db->single_select("SELECT NOW()");
62 # insert MOBILE Argument in the database-field if any
64 if($args =~ /MOBILE\s*=\s*(\d+)/){
68 my $hash = {'GAME' => $self->{-game},
76 # insert a phase-2 command
77 $hash->{'EXEC'} = $exec;
78 $hash->{'ACK'} = $now;
80 $hash->{'EXEC'} = $now;
82 $hash->{'LOCATION'} = $loc if defined $loc;
83 $db->insert_hash('COMMAND',$hash);
84 Util::log("command inserted: $cmd, $args, $loc, $player",1);
88 my ($self, $fields) = @_;
89 # $fields should NOT be empty
90 return $self->{-db}->select_array('MAP',"LOCATION,$fields","GAME=$self->{-game}");
98 my ($self, $fields) = @_;
99 $fields = ','.$fields if $fields;
100 $fields = 'ID'.$fields;
101 my $cond = "GAME=$self->{-game} AND (MTO=0 OR MTO=$self->{-user})";
102 return $self->{-db}->select_array('MESSAGE', $fields, $cond, 'TIME desc');
105 # sends a raw text, if $hash is not a hash. if it is one, it generates
106 # a tag with arguments usable by DataBase::long_loc()
108 my($self,$user,$hash) = @_;
110 $hash->{'MTO'} = $user;
111 $hash->{'GAME'} = $self->{-game};
113 $self->{-db}->send_message($hash);
117 sub send_message_to_me{
118 my ($self,$hash) = @_;
120 $self->send_message_to($self->{-user},$hash);
123 sub send_message_to_list{
124 my ($self,$msg_hash,@list) = @_;
126 Util::log("send_message_to_list(@list)",2);
128 for my $user (@list) {
129 my %copy = (%$msg_hash);
130 $self->send_message_to($user,\%copy);
134 sub send_message_to_all{
135 my ($self,$hash) = @_;
137 my @roles = $self->get_all_roles();
138 $self->send_message_to_list($hash,@roles);
144 my ($time, $from, $text, @args) = $self->{-db}->read_message($id);
148 $from = $from == 0 ? "Server" : $self->charname($from);
150 my $return = "<strong>$from $time:</strong> $text";
151 $return .= ' <a href="player.epl?cmd=SEND_MSG&other='.$other
152 .'">reply</a>' unless $other == 0;
156 sub delete_all_messages{
157 my ($self,$time) = @_;
158 # $::conf->{-EPL_DEBUG} = 2;
159 # print "time: $time<p>";
160 $self->{-db}->delete_from('MESSAGE',"GAME=$self->{-game} AND MTO=$self->{-user}".
161 " AND TIME < '$time'");
162 # $::conf->{-EPL_DEBUG} = 0;
165 # send message to all players, who see this field
166 sub send_message_to_field{
167 my($self,$loc,$hash) = @_;
169 return unless $::conf->{-SEND_MESSAGE_TO_FIELD};
171 my @players = $self->player_see_field($loc);
172 $self->send_message_to_list($hash,@players);
179 # returns a ref to a list of Event-IDs for a role
180 # it includes all game-events and all events on locations seen by the role
181 # TODO: accept additional parameter N to return the N newest events
185 my $db = $self->{-db};
186 my @loc = $self->seen_locations();
188 my $k = $db->select_hash('EVENT','LOCATION','ID',"GAME=$self->{-game}");
192 push @ret, $k->{$l} if (defined $k->{$l});
198 # returns a ref to a list of Event-IDs for a field
199 # it includes all events on locations
201 my ($self, $loc) = @_;
202 my $db = $self->{-db};
203 my $qloc = $db->quote($loc);
204 return $db->select_hash('EVENT','ID',0,"GAME=$self->{-game} AND LOCATION=$qloc");
208 my ($self, $id, $show_field) = @_;
210 $show_field = 1 unless defined $show_field and $show_field == 0;
212 my ($from, $time, $text, @args) = $self->{-db}->read_event($id);
215 if ($from != 'Game') {
216 $from = '<a href ="mapframe.epl?field='.$from.'">'."$from</a>";
220 $time = $self->{-db}->relative($time);
221 $from = "" unless $show_field;
222 return "<strong>$from $time:</strong> $text";
226 my ($self,$tag,$location) = @_;
228 $tag = 'EVENT_' . $tag;
229 ($tag,$location) = $self->{-db}->quote_all($tag,$location);
230 return $self->{-db}->single_hash_select('EVENT',"TAG=$tag and LOCATION=$location");
237 # Should be overloaded by derived class
244 my ($self,$field,$loc) = @_;
245 $loc = $self->{-db}->quote($loc);
246 my $stmt = "SELECT $field from MAP where GAME=$self->{-game} AND LOCATION=$loc";
247 return $self->{-db}->single_select($stmt);
250 sub read_player_relations{
251 my ($self, $user) = @_;
252 $user = $self->{-user} unless defined $user;
254 # print "user: $user\n";
255 my $r = $self->{-db}->select_hash('ALLIANCE', 'OTHER', 'STATUS',
256 "GAME=$self->{-game} AND PLAYER=$user");
261 sub read_single_relation{
262 my ($self,$me,$you) = @_;
263 my $hash = $self->{-db}->single_hash_select('ALLIANCE',
264 "GAME=$self->{-game} AND ".
267 my $ret = $hash->{'STATUS'};
268 return $ret ? $ret : 'NEUTRAL';
272 sub reverse_player_relations{
274 return $self->{-db}->select_hash('ALLIANCE', 'PLAYER', 'STATUS',
275 "GAME=$self->{-game} AND OTHER=$self->{-user}");
279 my ($self,$fields,$type,$loc,$only_available) = @_;
280 $only_available = 0 unless defined $only_available;
281 # print "read_mobile($fields,$type,$loc,$only_available)\n";
282 my $cond = "GAME=$self->{-game} AND LOCATION=$loc";
283 if ($only_available > 0) {
284 $cond .= " AND AVAILABLE=Y";
285 } elsif ($only_available < 0) {
286 $cond .= " AND AVAILABLE=N";
288 $cond .= " AND TYPE=$type" if $type;
289 return $self->{-db}->select_array('MOBILE', $fields, $cond);
292 sub read_mobile_condition{
293 my ($self,$fields,$cond,$loc) = @_;
294 $cond = "GAME=$self->{-game} AND $cond";
295 $cond .= " AND LOCATION=$loc" if defined $loc;
296 $self->{-db}->select_array('MOBILE',$fields,$cond);
299 # counts available mobiles of TYPE and OWNER (or all owners) in LOCATION
300 # TODO: we can do this in SQL with "select sum(COUNT) from MOBILE where ..."
302 my ($self,$type,$loc,$owner) = @_;
304 my $mobs = $self->read_mobile('COUNT,OWNER',$type,$loc,1);
306 for my $mob (@$mobs) {
308 if (defined $owner) {
309 $count += $nr if $mob->[1] == $owner;
317 # count all people in $loc from $player
319 my($self,$loc,$player) = @_;
320 $player = $self->{-user} unless defined $player;
322 my $cond = $self->{-db}->quote_condition("GAME=$self->{-game} ".
323 "AND OWNER=$player ".
325 "AND LOCATION=$loc");
326 my $stmt = "select sum(COUNT) from MOBILE where $cond";
327 my ($ret) = $self->{-db}->single_select($stmt);
330 # stupid, GAME not necessary: ID is unique between different games
331 sub get_mobile_info {
332 my ($self, $mob_id, $fields) = @_;
333 my $stmt = "SELECT $fields from MOBILE where GAME=$self->{-game} AND ID=$mob_id";
334 return $self->{-db}->single_select($stmt);
337 # WARNING: in Aymargeddon, this is overloaded in Aymargeddon.pm
339 my($self,$loc,$player,$active) = @_;
340 # $loc = $self->{-db}->quote($loc);
341 my $cond = "GAME=$self->{-game} AND LOCATION=$loc".
342 " AND (OWNER=$player OR ADORING=$player)";
343 if (defined $active) {
344 # my $y = $self->{-db}->quote('Y');
345 $cond .= " AND AVAILABLE=Y";
347 return $self->{-db}->select_array('MOBILE','ID',$cond);
351 my ($self,$player,$field) = @_;
352 my $stmt = "SELECT $field from ROLE where GAME=$self->{-game} AND PLAYER=$player";
353 return $self->{-db}->single_select($stmt);
357 my ($self,$role) = @_;
359 my $cond = "GAME=$self->{-game}";
361 # $role = $self->{-db}->quote($role);
362 $cond .= " AND ROLE=$role";
364 my @roles = @{$self->{-db}->select_array('ROLE','PLAYER',$cond)};
365 for my $i (0..$#roles) {
366 $roles[$i] = $roles[$i]->[0];
373 my ($ret,$run) = $self->{-db}->single_select("select SPEED, RUNNING from GAME".
374 " where GAME = $self->{-game} ");
375 return $run eq 'Y' ? $ret : - $ret;
379 my ($self,$player,$do) = @_;
380 return $self->{-db}->loc('UNASSIGNED') if $player < 1;
381 my @list = $self->read_role($player, 'NICKNAME');
386 my ($self,$player) = @_;
387 return 'OBSERVER' if $player < 1;
388 my @role = $self->read_role($player, 'ROLE');