ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/anim.C
Revision: 1.27
Committed: Sun Jul 1 05:00:17 2007 UTC (16 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_2, rel-2_3
Changes since 1.26: +11 -12 lines
Log Message:
- upgrade crossfire trt to the GPL version 3 (hopefully correctly).
- add a single file covered by the GNU Affero General Public License
  (which is not yet released, so I used the current draft, which is
  legally a bit wavy, but its likely better than nothing as it expresses
  direct intent by the authors, and we can upgrade as soon as it has been
  released).
  * this should ensure availability of source code for the server at least
    and hopefully also archetypes and maps even when modified versions
    are not being distributed, in accordance of section 13 of the agplv3.

File Contents

# Content
1 /*
2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 *
4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 * Copyright (©) 2002-2003,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 *
8 * Crossfire TRT is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * The authors can be reached via e-mail to <crossfire@schmorp.de>
22 */
23
24 /* This file contains animation related code. */
25
26 #include <global.h>
27 #include <stdio.h>
28
29 animhash_t animhash;
30 std::vector<animation> animations;
31
32 void
33 animation::resize (int new_size)
34 {
35 sfree <faceidx> (faces, num_animations);
36 num_animations = new_size;
37 faces = salloc<faceidx> (num_animations);
38 }
39
40 animation &
41 animation::create (const char *name, uint8 frames, uint8 facings)
42 {
43 if (animations.size () == MAXANIMNUM)
44 cleanup ("trying to create new animation, but MAXANIMNUM animations in use.");
45
46 animations.push_back (animation ());
47 animation &anim = animations.back ();
48
49 anim.number = animations.size () - 1;
50 anim.name = name;
51 anim.num_animations = frames;
52 anim.facings = facings;
53 anim.faces = salloc<faceidx> (frames);
54
55 animhash.insert (std::make_pair (anim.name, anim.number));
56
57 return anim;
58 }
59
60 animation &
61 animation::find (const char *name)
62 {
63 if (!name)
64 return animations [0];
65
66 animhash_t::iterator i = animhash.find (name);
67 return animations [i == animhash.end () ? 0 : i->second];
68 }
69
70 void
71 init_anim (void)
72 {
73 animation &anim0 = animation::create ("none", 1, 0);
74 anim0.faces [0] = 0;
75 }
76
77 /* Tries to find the animation id that matches name. Returns an integer match
78 * 0 if no match found (animation 0 is initialised as the 'bug' face
79 */
80 //TODO: nuke this function and replace all occurences by animations::find
81 int
82 find_animation (const char *name)
83 {
84 return animation::find (name).number;
85 }
86
87 /*
88 * animate_object(object) updates the face-variable of an object.
89 * If the object is the head of a multi-object, all objects are animated.
90 * op is the object to animate.
91 * dir is the direction the object is facing. This is generally same as
92 * op->direction, but in some cases, op->facing is used instead - the
93 * caller has a better idea which one it really wants to be using,
94 * so let it pass along the right one.
95 */
96 void
97 animate_object (object *op, int dir)
98 {
99 int max_state; /* Max animation state object should be drawn in */
100 int base_state; /* starting index # to draw from */
101
102 if (!op->animation_id || !NUM_ANIMATIONS (op))
103 {
104 LOG (llevError, "Object %s lacks animation.\n", op->debug_desc ());
105 CLEAR_FLAG (op, FLAG_ANIMATE);
106 return;
107 }
108
109 if (op->head_ () != op)
110 {
111 dir = op->head->direction;
112
113 if (NUM_ANIMATIONS (op) == NUM_ANIMATIONS (op->head))
114 op->state = op->head->state;
115 else
116 ++op->state;
117 }
118 else
119 ++op->state; /* increase draw state */
120
121 /* If object is turning, then max animation state is half through the
122 * animations. Otherwise, we can use all the animations.
123 */
124 max_state = NUM_ANIMATIONS (op) / NUM_FACINGS (op);
125 base_state = 0;
126 /* at least in the older animations that used is_turning, the first half
127 * of the animations were left facing, the second half right facing.
128 * Note in old the is_turning, it was set so that the animation for a monster
129 * was always towards the enemy - now it is whatever direction the monster
130 * is facing.
131 */
132
133 if (NUM_FACINGS (op) == 2)
134 {
135 if (dir < 5)
136 base_state = 0;
137 else
138 base_state = NUM_ANIMATIONS (op) / 2;
139 }
140 else if (NUM_FACINGS (op) == 4)
141 {
142 if (dir == 0)
143 base_state = 0;
144 else
145 base_state = ((dir - 1) / 2) * (NUM_ANIMATIONS (op) / 4);
146 }
147 else if (NUM_FACINGS (op) == 8)
148 {
149 if (dir == 0)
150 base_state = 0;
151 else
152 base_state = (dir - 1) * (NUM_ANIMATIONS (op) / 8);
153 }
154
155 /* If beyond drawable states, reset */
156 if (op->state >= max_state)
157 op->state = 0;
158
159 SET_ANIMATION (op, op->state + base_state);
160
161 if (op->face == blank_face)
162 op->invisible = 1;
163
164 /* This block covers monsters (eg, pixies) which are supposed to
165 * cycle from visible to invisible and back to being visible.
166 * as such, disable it for players, as then players would become
167 * visible.
168 */
169 else if (op->type != PLAYER && op->arch->flag [FLAG_ALIVE])
170 {
171 if (op->face == 0)
172 {
173 op->invisible = 1;
174 CLEAR_FLAG (op, FLAG_ALIVE);
175 }
176 else
177 {
178 op->invisible = 0;
179 SET_FLAG (op, FLAG_ALIVE);
180 }
181 }
182
183 if (op->more)
184 animate_object (op->more, dir);
185
186 /* update_object will also recursively update all the pieces.
187 * as such, we call it last, and only call it for the head
188 * piece, and not for the other tail pieces.
189 */
190 if (op->head_ () == op)
191 update_object (op, UP_OBJ_FACE);
192 }
193