~alaxa27/ultimate-smash-friends/mirror_trunk

« back to all changes in this revision

Viewing changes to pkg/ultimate-smash-friends_1.0-beta-1/usr/lib/usf_modules/entity_skin.py

  • Committer: gaby
  • Date: 2009-11-30 17:03:16 UTC
  • Revision ID: gaby@ks22672.kimsufi.com-20091130170316-6lm3v7q0torulfab
adding code package

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
################################################################################
 
2
# copyright 2008 Gabriel Pettier <gabriel.pettier@gmail.com>                   #
 
3
#                                                                              #
 
4
# This file is part of UltimateSmashFriends                                    #
 
5
#                                                                              #
 
6
# UltimateSmashFriends is free software: you can redistribute it and/or modify #
 
7
# it under the terms of the GNU General Public License as published by         #
 
8
# the Free Software Foundation, either version 3 of the License, or            #
 
9
# (at your option) any later version.                                          #
 
10
#                                                                              #
 
11
# UltimateSmashFriends is distributed in the hope that it will be useful,      #
 
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
 
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                #
 
14
# GNU General Public License for more details.                                 #
 
15
#                                                                              #
 
16
# You should have received a copy of the GNU General Public License            #
 
17
# along with UltimateSmashFriends.  If not, see <http://www.gnu.org/licenses/>.#
 
18
################################################################################
 
19
 
 
20
import sys
 
21
import pygame
 
22
 
 
23
from animations import Frame, PreciseTimedAnimation
 
24
import loaders
 
25
import game
 
26
import timed_event
 
27
from debug_utils import LOG
 
28
from config import config
 
29
 
 
30
# different in python 2.4 and 2.5
 
31
if sys.version_info[0] == 2 and sys.version_info[1] >= 5:
 
32
    from xml.etree import ElementTree
 
33
else:
 
34
    from elementtree import ElementTree
 
35
 
 
36
import os, sys
 
37
import random
 
38
 
 
39
class Entity_skin (object):
 
40
    """
 
41
    An Entity_skin contains all information about a player or an item, which is
 
42
    mainly animations frames, with their timings and vectors, and less 
 
43
    importants information as the character/item name and such details.
 
44
 
 
45
    """
 
46
    def __init__( self, dir_name="characters"+os.sep+"stick-tiny",
 
47
    server=False, xml_from_str=None):
 
48
        """
 
49
        The dir_name is the relative path of the directory where the item/player
 
50
        is defined, the class search for an xml file of the same name as the
 
51
        directory there.
 
52
 
 
53
        """
 
54
        #LOG().log(dir_name)
 
55
        self.animations = {}
 
56
        if xml_from_str is not None:
 
57
            a = ElementTree.ElementTree()
 
58
            # FIXME this is DIRTY
 
59
            f = open('/tmp/erf','w')
 
60
            f.write(xml_from_str)
 
61
            f.close()
 
62
            a.parse('/tmp/erf')
 
63
 
 
64
        else:
 
65
            file = os.path.join(
 
66
                        config['MEDIA_DIRECTORY'],
 
67
                        dir_name,
 
68
                        dir_name.split(os.sep)[-1]
 
69
                        +os.extsep+'xml'
 
70
                        )
 
71
            #LOG().log(file)
 
72
            a = ElementTree.ElementTree(
 
73
                    None,
 
74
                    file
 
75
                    )
 
76
 
 
77
        attribs = a.getroot().attrib
 
78
 
 
79
        self.filename = dir_name
 
80
        self.name = attribs['name']
 
81
 
 
82
        if not server:
 
83
            self.image = loaders.image(
 
84
                    os.path.join(
 
85
                        config['MEDIA_DIRECTORY'],
 
86
                        dir_name,
 
87
                        attribs['image']
 
88
                        )
 
89
                    )[0]
 
90
 
 
91
        self.weigh = attribs['weight']
 
92
        if 'armor' in attribs:
 
93
            self.armor = int(attribs['armor'])
 
94
        else:
 
95
            self.armor = 0
 
96
        self.action_events = {}
 
97
        self.sounds = {}
 
98
        self.vectors = {}
 
99
 
 
100
        self.hardshape = pygame.Rect(
 
101
                [
 
102
                int(i) for i
 
103
                in attribs['hardshape'].split(' ')
 
104
                ]
 
105
                )
 
106
 
 
107
        for movement in a.findall('movement'):
 
108
            frames = []
 
109
            events = []
 
110
            sounds = []
 
111
            vectors = []
 
112
 
 
113
            for event in movement.findall('vector'):
 
114
                #LOG().log('vector found')
 
115
                x,y = [int(n) for n in event.attrib['vector'].split(',')]
 
116
                vectors.append(
 
117
                        (
 
118
                        (x,y),
 
119
                         int(event.attrib['time'])
 
120
                        )
 
121
                        )
 
122
 
 
123
            self.vectors[movement.attrib['name']] = vectors
 
124
 
 
125
            for event in movement.findall('event'):
 
126
                events.append(
 
127
                        (
 
128
                         event.attrib['action'],
 
129
                         [
 
130
                         int(i)\
 
131
                         for i in event.attrib['period'].split(',')
 
132
                         ]
 
133
                        )
 
134
                        )
 
135
 
 
136
            self.action_events[movement.attrib['name']] = events
 
137
 
 
138
            for sound in movement.findall('sound'):
 
139
                sounds.append(
 
140
                        pygame.mixer.Sound(
 
141
                            os.path.join(
 
142
                                config['MEDIA_DIRECTORY'],
 
143
                                dir_name,
 
144
                                sound.attrib['filename']
 
145
                                )
 
146
                            )
 
147
                        )
 
148
 
 
149
            self.sounds[movement.attrib['name']] = sounds
 
150
 
 
151
            for frame in movement.findall('frame'):
 
152
                image = os.path.join(
 
153
                            config['MEDIA_DIRECTORY'],
 
154
                            dir_name,
 
155
                            frame.attrib['image']
 
156
                            )
 
157
 
 
158
                frames.append(
 
159
                        Frame(
 
160
                            image,
 
161
                            frame.attrib['time'],
 
162
                            ('hardshape' in frame.attrib
 
163
                             and frame.attrib ['hardshape']
 
164
                             or loaders.image(image)[1]),
 
165
                            name=frame.attrib['image']
 
166
                            )
 
167
                        )
 
168
 
 
169
                for agressiv in frame.findall( 'agressiv-point' ):
 
170
                    coords = agressiv.attrib[ 'coords' ].split( ',' )
 
171
                    vector = agressiv.attrib[ 'vector' ].split( ',' )
 
172
                    frames[-1].addAgressivPoint([int(i) for i in coords],
 
173
                                                [int(i) for i in vector])
 
174
 
 
175
            self.animations[movement.attrib['name']] = PreciseTimedAnimation(
 
176
                    frames,
 
177
                    movement.attrib,
 
178
                    server
 
179
                    )
 
180
 
 
181
        self.current_animation = "static"
 
182
        self.animation = self.animations[self.current_animation]
 
183
        self.animation_change = 1
 
184
 
 
185
    def __del__(self):
 
186
        del(self.__dict__)
 
187
        del(self)
 
188
 
 
189
    def change_animation( self, anim_name, game, params={}):
 
190
        """
 
191
        Change animation of the entity skin, updating hardshape and agressiv
 
192
        points. Add associated events to game.
 
193
 
 
194
        """
 
195
        #LOG().log(params,1)
 
196
        if ( anim_name in self.animations
 
197
                and ( anim_name == "static"
 
198
                    or anim_name != self.current_animation )):
 
199
            if 'entity' in params and params['entity'].upgraded:
 
200
                if anim_name+'_upgraded' in self.animations:
 
201
                    self.current_animation = anim_name+'_upgraded'
 
202
                else:
 
203
                    LOG().log(self.name+' character has no upgraded \
 
204
version of '+anim_name+' falling back to normal version')
 
205
                    self.current_animation = anim_name
 
206
            else:
 
207
                self.current_animation = anim_name
 
208
 
 
209
            self.animation_change = 1
 
210
            params['world'] = game
 
211
            params['gametime'] = game.gametime
 
212
            for event in self.action_events[anim_name]:
 
213
                if event[1][0] is 0:
 
214
                    p1 = None
 
215
                else:
 
216
                    p1 = game.gametime+(event[1][0]/1000.0)
 
217
 
 
218
                if event[1][1] is 0:
 
219
                    p2 = None
 
220
                else:
 
221
                    p2 = game.gametime+(event[1][1]/1000.0)
 
222
 
 
223
                try:
 
224
                    game.events.append(
 
225
                            timed_event.event_names[event[0]]
 
226
                            (
 
227
                             period=(p1, p2),
 
228
                             params=params
 
229
                            )
 
230
                            )
 
231
 
 
232
                except AttributeError:
 
233
                    LOG().log((self.name, game), 3)
 
234
                    raise
 
235
 
 
236
            #LOG().log(self.vectors[anim_name])
 
237
            for vector in self.vectors[anim_name]:
 
238
                #LOG().log('vector added')
 
239
                params2 = params.copy() # because we want to change some of
 
240
                                        # them for this time.
 
241
                params2['vector'] = vector[0]
 
242
                params2['anim_name'] = anim_name
 
243
                game.events.append(
 
244
                        timed_event.VectorEvent(
 
245
                             period=(None, game.gametime+vector[1]/1000.0),
 
246
                             params=params2
 
247
                            )
 
248
                        )
 
249
 
 
250
            if self.sounds[anim_name] != []:
 
251
                random.choice(self.sounds[anim_name]).play()
 
252
        else:
 
253
            #LOG().log( "entity_skin "+self.name+" has no "+anim_name+"\
 
254
#animation.")
 
255
            pass
 
256
 
 
257
    def update(self, t, reversed=False):
 
258
        """
 
259
        Update the skin's animation if necessary.
 
260
 
 
261
        """
 
262
        if self.animation.playing == 0:
 
263
            self.current_animation = "static"
 
264
            self.animation_change = True
 
265
        if self.animation_change:
 
266
            self.animation = self.animations[self.current_animation]
 
267
            self.animation_change = False
 
268
            self.animation.start(t)
 
269
        self.animation.update(t, reversed)
 
270