2 ##########################################################################
4 # Copyright (c) 2003 Aymargeddon Development Team
7 # "FROGS" = Framework for Realtime Online Games of Strategy
9 # FROGS is free software; you can redistribute it and/or modify it
10 # under the terms of the GNU General Public License as published by the Free
11 # Software Foundation; either version 2 of the License, or (at your option)
14 # FROGS is distributed in the hope that it will be useful, but WITHOUT
15 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 # You should have received a copy of the GNU General Public License along
19 # with this program; if not, write to the Free Software Foundation, Inc., 675
20 # Mass Ave, Cambridge, MA 02139, USA.
22 ###########################################################################
25 # generell Game-specific functions
36 my ($class,$game,$user,$db) = @_;
40 # create database-object, if not given with call
44 $self->{-db} = DataBase->new();
46 # $db->set_language($lang);
48 $self->{-game} = $game;
49 $self->{-user} = $user;
55 my ($self,$cmd,$args,$loc,$player,$exec) = @_;
56 $player = $self->{-user} unless defined $player;
57 my $db = $self->{-db};
59 my ($now) = $db->single_select("SELECT NOW()");
61 # insert MOBILE Argument in the database-field if any
63 if($args =~ /MOBILE\s*=\s*(\d+)/){
67 my $hash = {'GAME' => $self->{-game},
75 # insert a phase-2 command
76 $hash->{'EXEC'} = $exec;
77 $hash->{'ACK'} = $now;
79 $hash->{'EXEC'} = $now;
81 $hash->{'LOCATION'} = $loc if defined $loc;
82 $db->insert_hash('COMMAND',$hash);
83 Util::log("command inserted: $cmd, $args, $loc, $player",1);
87 my ($self, $fields) = @_;
88 # $fields should NOT be empty
89 return $self->{-db}->select_array('MAP',"LOCATION,$fields","GAME=$self->{-game}");
97 my ($self, $fields) = @_;
98 $fields = ','.$fields if $fields;
99 $fields = 'ID'.$fields;
100 my $cond = "GAME=$self->{-game} AND (MTO=0 OR MTO=$self->{-user})";
101 return $self->{-db}->select_array('MESSAGE', $fields, $cond, 'TIME desc');
104 # sends a raw text, if $hash is not a hash. if it is one, it generates
105 # a tag with arguments usable by DataBase::long_loc()
107 my($self,$user,$hash) = @_;
109 $hash->{'MTO'} = $user;
110 $hash->{'GAME'} = $self->{-game};
112 $self->{-db}->send_message($hash);
116 sub send_message_to_me{
117 my ($self,$hash) = @_;
119 $self->send_message_to($self->{-user},$hash);
122 sub send_message_to_list{
123 my ($self,$msg_hash,@list) = @_;
125 Util::log("send_message_to_list(@list)",2);
127 for my $user (@list) {
128 my %copy = (%$msg_hash);
129 $self->send_message_to($user,\%copy);
133 sub send_message_to_all{
134 my ($self,$hash) = @_;
136 my @roles = $self->get_all_roles();
137 $self->send_message_to_list($hash,@roles);
143 my ($time, $from, $text, @args) = $self->{-db}->read_message($id);
147 $from = $from == 0 ? "Server" : $self->charname($from);
149 my $return = "<strong>$from $time:</strong> $text";
150 $return .= ' <a href="player.epl?cmd=SEND_MSG&other='.$other
151 .'">reply</a>' unless $other == 0;
155 sub delete_all_messages{
156 my ($self,$time) = @_;
157 # $::conf->{-EPL_DEBUG} = 2;
158 # print "time: $time<p>";
159 $self->{-db}->delete_from('MESSAGE',"GAME=$self->{-game} AND MTO=$self->{-user}".
160 " AND TIME < '$time'");
161 # $::conf->{-EPL_DEBUG} = 0;
164 # send message to all players, who see this field
165 sub send_message_to_field{
166 my($self,$loc,$hash) = @_;
168 return unless $::conf->{-SEND_MESSAGE_TO_FIELD};
170 my @players = $self->player_see_field($loc);
171 $self->send_message_to_list($hash,@players);
178 # returns a ref to a list of Event-IDs for a role
179 # it includes all game-events and all events on locations seen by the role
180 # TODO: accept additional parameter N to return the N newest events
184 my $db = $self->{-db};
185 my @loc = $self->seen_locations();
187 my $k = $db->select_hash('EVENT','LOCATION','ID',"GAME=$self->{-game}");
191 push @ret, $k->{$l} if (defined $k->{$l});
197 # returns a ref to a list of Event-IDs for a field
198 # it includes all events on locations
200 my ($self, $loc) = @_;
201 my $db = $self->{-db};
202 my $qloc = $db->quote($loc);
203 return $db->select_hash('EVENT','ID',0,"GAME=$self->{-game} AND LOCATION=$qloc");
207 my ($self, $id, $show_field) = @_;
209 $show_field = 1 unless defined $show_field and $show_field == 0;
211 my ($from, $time, $text, @args) = $self->{-db}->read_event($id);
214 if ($from != 'Game') {
215 $from = '<a href ="mapframe.epl?field='.$from.'">'."$from</a>";
219 $time = $self->{-db}->relative($time);
220 $from = "" unless $show_field;
221 return "<strong>$from $time:</strong> $text";
225 my ($self,$tag,$location) = @_;
227 $tag = 'EVENT_' . $tag;
228 ($tag,$location) = $self->{-db}->quote_all($tag,$location);
229 return $self->{-db}->single_hash_select('EVENT',"TAG=$tag and LOCATION=$location");
236 # Should be overloaded by derived class
243 my ($self,$field,$loc) = @_;
244 $loc = $self->{-db}->quote($loc);
245 my $stmt = "SELECT $field from MAP where GAME=$self->{-game} AND LOCATION=$loc";
246 return $self->{-db}->single_select($stmt);
249 sub read_player_relations{
250 my ($self, $user) = @_;
251 $user = $self->{-user} unless defined $user;
253 # print "user: $user\n";
254 my $r = $self->{-db}->select_hash('ALLIANCE', 'OTHER', 'STATUS',
255 "GAME=$self->{-game} AND PLAYER=$user");
260 sub read_single_relation{
261 my ($self,$me,$you) = @_;
262 my $hash = $self->{-db}->single_hash_select('ALLIANCE',
263 "GAME=$self->{-game} AND ".
266 my $ret = $hash->{'STATUS'};
267 return $ret ? $ret : 'NEUTRAL';
271 sub reverse_player_relations{
273 return $self->{-db}->select_hash('ALLIANCE', 'PLAYER', 'STATUS',
274 "GAME=$self->{-game} AND OTHER=$self->{-user}");
278 my ($self,$fields,$type,$loc,$only_available) = @_;
279 $only_available = 0 unless defined $only_available;
280 # print "read_mobile($fields,$type,$loc,$only_available)\n";
281 my $cond = "GAME=$self->{-game} AND LOCATION=$loc";
282 if ($only_available > 0) {
283 $cond .= " AND AVAILABLE=Y";
284 } elsif ($only_available < 0) {
285 $cond .= " AND AVAILABLE=N";
287 $cond .= " AND TYPE=$type" if $type;
288 return $self->{-db}->select_array('MOBILE', $fields, $cond);
291 sub read_mobile_condition{
292 my ($self,$fields,$cond,$loc) = @_;
293 $cond = "GAME=$self->{-game} AND $cond";
294 $cond .= " AND LOCATION=$loc" if defined $loc;
295 $self->{-db}->select_array('MOBILE',$fields,$cond);
298 # counts available mobiles of TYPE and OWNER (or all owners) in LOCATION
299 # TODO: we can do this in SQL with "select sum(COUNT) from MOBILE where ..."
301 my ($self,$type,$loc,$owner) = @_;
303 my $mobs = $self->read_mobile('COUNT,OWNER',$type,$loc,1);
305 for my $mob (@$mobs) {
307 if (defined $owner) {
308 $count += $nr if $mob->[1] == $owner;
316 # count all people in $loc from $player
318 my($self,$loc,$player) = @_;
319 $player = $self->{-user} unless defined $player;
321 my $cond = $self->{-db}->quote_condition("GAME=$self->{-game} ".
322 "AND OWNER=$player ".
324 "AND LOCATION=$loc");
325 my $stmt = "select sum(COUNT) from MOBILE where $cond";
326 my ($ret) = $self->{-db}->single_select($stmt);
329 # stupid, GAME not necessary: ID is unique between different games
330 sub get_mobile_info {
331 my ($self, $mob_id, $fields) = @_;
332 my $stmt = "SELECT $fields from MOBILE where GAME=$self->{-game} AND ID=$mob_id";
333 return $self->{-db}->single_select($stmt);
336 # WARNING: in Aymargeddon, this is overloaded in Aymargeddon.pm
338 my($self,$loc,$player,$active) = @_;
339 # $loc = $self->{-db}->quote($loc);
340 my $cond = "GAME=$self->{-game} AND LOCATION=$loc".
341 " AND (OWNER=$player OR ADORING=$player)";
342 if (defined $active) {
343 # my $y = $self->{-db}->quote('Y');
344 $cond .= " AND AVAILABLE=Y";
346 return $self->{-db}->select_array('MOBILE','ID',$cond);
350 my ($self,$player,$field) = @_;
351 my $stmt = "SELECT $field from ROLE where GAME=$self->{-game} AND PLAYER=$player";
352 return $self->{-db}->single_select($stmt);
356 my ($self,$role) = @_;
358 my $cond = "GAME=$self->{-game}";
360 # $role = $self->{-db}->quote($role);
361 $cond .= " AND ROLE=$role";
363 my @roles = @{$self->{-db}->select_array('ROLE','PLAYER',$cond)};
364 for my $i (0..$#roles) {
365 $roles[$i] = $roles[$i]->[0];
372 my ($ret,$run) = $self->{-db}->single_select("select SPEED, RUNNING from GAME".
373 " where GAME = $self->{-game} ");
374 return $run eq 'Y' ? $ret : - $ret;
378 my ($self,$player,$do) = @_;
379 return $self->{-db}->loc('UNASSIGNED') if $player < 1;
380 my @list = $self->read_role($player, 'NICKNAME');
385 my ($self,$player) = @_;
386 return 'OBSERVER' if $player < 1;
387 my @role = $self->read_role($player, 'ROLE');