ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/gde/GCE/ArchRef.pm
Revision: 1.2
Committed: Mon Aug 28 18:24:49 2006 UTC (17 years, 9 months ago) by elmex
Branch: MAIN
Changes since 1.1: +6 -6 lines
Log Message:
finished attachment editor mostly, only multiline editing is still missing :(

File Contents

# Content
1 package GCE::ArchRef;
2 =head1 NAME
3
4 GCE::ArchRef - a intelligent reference to an arch instance on/in the map
5
6 =head1 SYNOPSIS
7
8 GCE::ArchRef->new (arch => <hashref>, cb => <changecb>)
9
10 =over 4
11
12 =cut
13
14 use Storable qw/dclone/;
15 use Crossfire;
16 use Carp;
17 use GCE::Util;
18
19 sub getarch {
20 my ($ar) = @_;
21
22 if (ref $ar eq 'GCE::ArchRef') {
23 return $ar->{arch}
24 } else {
25 return $ar
26 }
27 }
28
29 sub new {
30 my $class = shift;
31 my $self = { @_ };
32 bless $self, $class;
33
34 unless (defined $self->{arch}) {
35 Carp::confess ("arch not defined when making new ArchRef")
36 }
37 unless (defined $Crossfire::ARCH{$self->getarch->{_name}}) {
38 Carp::confess ("archetype not defined")
39 }
40
41 return $self;
42 }
43
44 sub type {
45 my ($self) = @_;
46 Crossfire::arch_attr $self->getarch;
47 }
48
49 sub archetype {
50 my ($self) = @_;
51
52 $Crossfire::ARCH{$self->getarch->{_name}};
53 }
54
55 sub longname {
56 my ($self) = @_;
57
58 my $name = $self->get ('_name');
59 my $rname = $self->get ('name');
60 my $t = $self->type;
61
62 $name . ($rname ? " - $rname" : "") . " ($t->{name})"
63 }
64
65 sub field_value_is_default {
66 my ($self, $key, $val) = @_;
67 my $al_arch = $self->archetype;
68
69 # XXX: Was '... and $val', does this fix problems?
70 (defined $al_arch->{$key} and $al_arch->{$key} ne $val)
71 || (not (defined $al_arch->{$key}) and $val)
72 }
73
74 sub add_inv {
75 my ($self, $arch) = @_;
76 push @{$self->{arch}->{inventory}}, dclone (getarch $arch);
77
78 $self->{cb}->($self)
79 if defined $self->{cb};
80
81 $self->exec_change_cbs (qw/inventory/);
82 }
83
84 sub swap_inv {
85 my ($self, $swapidx, $ownidx) = @_;
86 my $inv = $self->getarch->{inventory};
87
88 ($inv->[$swapidx], $inv->[$ownidx])
89 = ($inv->[$ownidx], $inv->[$swapidx]);
90
91 $self->{cb}->($self)
92 if defined $self->{cb};
93
94 $self->exec_change_cbs (qw/inventory/);
95 }
96
97 sub get_inv_refs {
98 my ($self) = @_;
99
100 my $cb = sub {
101 $self->{cb}->($self)
102 if defined $self->{cb};
103
104 $self->exec_change_cbs (qw/inventory/);
105 };
106
107 [ map { GCE::ArchRef->new (arch => $_, cb => $cb) } @{$self->get ('inventory') || []} ]
108 }
109
110 sub replace_inv {
111 my ($self, $idx, $new) = @_;
112 splice @{$self->getarch->{'inventory'}}, $idx, 1, $new;
113
114 $self->{cb}->($self)
115 if defined $self->{cb};
116
117 $self->exec_change_cbs (qw/inventory/);
118 }
119
120 sub remove_inv {
121 my ($self, $idx) = @_;
122 splice @{$self->getarch->{'inventory'}}, $idx, 1;
123
124 $self->{cb}->($self)
125 if defined $self->{cb};
126
127 $self->exec_change_cbs (qw/inventory/);
128 }
129
130 sub reset_to_defaults {
131 my ($self) = @_;
132
133 my $arch = $self->getarch;
134 for (keys %$arch) {
135 delete $arch->{$_} if $_ ne '_name'
136 }
137
138 $self->{cb}->($self)
139 if defined $self->{cb};
140
141 $self->exec_change_cbs;
142 }
143
144 sub get {
145 my ($self, $key) = @_;
146 $self->getarch->{$key}
147 }
148
149 sub get_or_default {
150 my ($self, $key) = @_;
151 def ($self->get ($key), $self->archetype->{$key})
152 }
153
154 sub set_silent {
155 my ($self, $key, $value) = @_;
156
157 my $arch = $self->getarch;
158 my $al_arch = $self->archetype; #$Crossfire::ARCH{$arch->{_name}};
159
160 if (ref $value) {
161 $arch->{$key} = $value;
162
163 } else {
164 if (not defined $al_arch->{$key}) {
165 if (not defined $value) {
166 # try to normalize
167 delete $arch->{$key};
168 } else {
169 # try to normalize
170 $arch->{$key} = $value;
171 }
172 } else {
173 if ($al_arch->{$key} ne $value) {
174 $arch->{$key} = $value;
175 } else {
176 # try to normalize
177 delete $arch->{$key};
178 }
179 }
180 }
181
182 $self->{cb}->($arch)
183 if defined $self->{cb};
184 }
185
186 sub set {
187 my ($self, $key, $value) = @_;
188 $self->set_silent ($key, $value);
189
190 $self->exec_change_cbs ($key);
191 }
192
193 sub remove_on_change {
194 my ($self, $key) = @_;
195 delete $self->{change_cbs}->{$key};
196 }
197
198 sub add_on_change {
199 my ($self, $key, $cb) = @_;
200 $self->{change_cbs}->{$key} = $cb;
201 }
202
203 sub exec_change_cbs {
204 my ($self, @a) = @_;
205 $_->($self, @a) for (values %{$self->{change_cbs}});
206 }
207
208 =head1 AUTHOR
209
210 Marc Lehmann <schmorp@schmorp.de>
211 http://home.schmorp.de/
212
213 Robin Redeker <elmex@ta-sa.org>
214 http://www.ta-sa.org/
215
216 =cut
217 1;