stratagus-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Stratagus-CVS] stratagus data/ccl/missiles.ccl data/ccl/spells...


From: Crestez Leonard
Subject: [Stratagus-CVS] stratagus data/ccl/missiles.ccl data/ccl/spells...
Date: Mon, 20 Oct 2003 20:18:32 -0400

CVSROOT:        /cvsroot/stratagus
Module name:    stratagus
Branch:         
Changes by:     Crestez Leonard <address@hidden>        03/10/20 20:18:31

Modified files:
        data/ccl       : missiles.ccl spells.ccl 
        doc            : ChangeLog.html 
        doc/ccl        : magic.html unittype.html 
        src/clone      : ccl_spell.c spells.c 
        src/include    : missile.h spells.h 
        src/missile    : ccl_missile.c missile.c 
        src/network    : lowlevel.c 

Log message:
        Commited jarod's latest smoke patch.

Patches:
Index: stratagus/data/ccl/missiles.ccl
diff -u stratagus/data/ccl/missiles.ccl:1.36 
stratagus/data/ccl/missiles.ccl:1.37
--- stratagus/data/ccl/missiles.ccl:1.36        Mon Oct 20 07:08:52 2003
+++ stratagus/data/ccl/missiles.ccl     Mon Oct 20 20:18:30 2003
@@ -26,7 +26,7 @@
 ;;      along with this program; if not, write to the Free Software
 ;;      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  
USA
 ;;
-;;     $Id: missiles.ccl,v 1.36 2003/10/20 11:08:52 n0body Exp $
+;;     $Id: missiles.ccl,v 1.37 2003/10/21 00:18:30 n0body Exp $
 
 ;;     NOTE: the missiles could be sorted for races, but did this make sense?
 
@@ -99,7 +99,7 @@
 
 (define-missile-type 'missile-whirlwind
   'file "missiles/tornado.png" 'size '(56 56) 'frames 4 'num-directions 1
-  'draw-level 50 'class 'missile-class-whirlwind 'sleep 1 'speed 2 'range 1)
+  'draw-level 50 'class 'missile-class-whirlwind 'sleep 1 'speed 2 'range 2)
 
 (define-missile-type 'missile-catapult-rock
   'file "missiles/catapult_rock.png" 'size '(32 32) 'frames 15 'num-directions 
5
Index: stratagus/data/ccl/spells.ccl
diff -u stratagus/data/ccl/spells.ccl:1.10 stratagus/data/ccl/spells.ccl:1.11
--- stratagus/data/ccl/spells.ccl:1.10  Mon Oct 20 07:08:53 2003
+++ stratagus/data/ccl/spells.ccl       Mon Oct 20 20:18:30 2003
@@ -26,7 +26,7 @@
 ;;      along with this program; if not, write to the Free Software

 ;;      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  
USA

 ;;

-;;     $Id: spells.ccl,v 1.10 2003/10/20 11:08:53 n0body Exp $

+;;     $Id: spells.ccl,v 1.11 2003/10/21 00:18:30 n0body Exp $

 

 ;; For documentation see stratagus/doc/ccl/ccl.html ;; FIXME write and move 
doc.

 

@@ -306,7 +306,7 @@
        'manacost 100

        'range  10

        'target 'position ;; FIXME position or organic target

-       'action '(death-coil damage 50)

+       'action '(fireball damage 50)

 ;      'condition '(UnitTypeflag (true organic))

        'sound-when-cast "death coil"

        'missile-when-cast "missile-death-coil"

@@ -329,7 +329,7 @@
        'manacost 100

        'range  12

        'target 'position

-       'action '(whirlwind duration 801) ; TODO damage1 4 damage2 1

+       'action '(whirlwind duration 801 damage 4) ; TODO damage1 4 damage2 1

        'sound-when-cast "whirlwind"

        'missile-when-cast "missile-whirlwind"

 ;;     'autocast '(range 12)

Index: stratagus/doc/ChangeLog.html
diff -u stratagus/doc/ChangeLog.html:1.556 stratagus/doc/ChangeLog.html:1.557
--- stratagus/doc/ChangeLog.html:1.556  Mon Oct 20 07:08:54 2003
+++ stratagus/doc/ChangeLog.html        Mon Oct 20 20:18:31 2003
@@ -2,7 +2,7 @@
 <html>
 <head>
 <!--
-----   $Id: ChangeLog.html,v 1.556 2003/10/20 11:08:54 n0body Exp $
+----   $Id: ChangeLog.html,v 1.557 2003/10/21 00:18:31 n0body Exp $
 
 ----   (c) Copyright 1998-2003 by Lutz Sammer
 
@@ -36,7 +36,8 @@
 <li>Future 2.00 Release<p>
     <ul>
     <li>++
-    <li>Made lots of missile changes, removed Missile::Controller.
+    <li>Applied  missile smoke patch #2133, fixed task #2786. (from Jarod 
Dauphin)
+    <li>Made lots of missile changes, removed Missile::Controller. (from 
Crestez Leonard)
     <li>Fixed Bug #6006: Crash saving building not built yet (from Russell 
Smith).
     <li>Fixed Bug: Failed Building Crashes Engine (from Russell Smith).
     <li>Remove old Master Server Code, began implementing a new one (from 
Russell Smith).
Index: stratagus/doc/ccl/magic.html
diff -u stratagus/doc/ccl/magic.html:1.2 stratagus/doc/ccl/magic.html:1.3
--- stratagus/doc/ccl/magic.html:1.2    Mon Oct 20 07:08:55 2003
+++ stratagus/doc/ccl/magic.html        Mon Oct 20 20:18:31 2003
@@ -182,6 +182,10 @@
 <dt>impact-missile</dt>
 <dd>You can use this to spawn another missile on impact. F.E. 'impact-missile 
'missile-explosion
 </dd>
+<dt>smoke-missile</dt>
+<dd>The name of the next (other) missile to generate a trailing smoke.  So it
+can be used to generate a chain of missiles.
+</dd>
 <dt>can-hit-owner</dt>
 <dd>This is a boolean value(#t or #f) that determines if the missile will 
affect
 the caster or not.
@@ -363,9 +367,13 @@
 <dd>The current position of the missile. It's list of and y values. 
Coordinates are
 in pixels, not tiles. F.E 'pos (4500 3450)
 </dd>
+<dt>origin-pos</dt>
+<dd>The starting position of the missile. It's list of and y values. 
Coordinates are
+in pixels, not tiles. F.E 'pos (4505 3455)
+</dd>
 <dt>goal</dt>
 <dd>The position of the missile's destination. It's list of and y values. 
Coordinates are
-in pixels, not tiles. F.E 'gold (4510 3500)
+in pixels, not tiles. F.E 'gold (4510 3460)
 </dd>
 <dt>local</dt>
 <dd>This unit is marked as local, and it's visible only to the player. This
@@ -425,7 +433,7 @@
 
 
 <hr>
-Last changed: $Id: magic.html,v 1.2 2003/10/20 11:08:55 n0body Exp $<br>
+Last changed: $Id: magic.html,v 1.3 2003/10/21 00:18:31 n0body Exp $<br>
 All trademarks and copyrights on this page are owned by their respective 
owners.
 <address>(c) 2002-2003 by <a href="http://stratagus.org";>
 The Stratagus Project</a></address></body></html>
Index: stratagus/doc/ccl/unittype.html
diff -u stratagus/doc/ccl/unittype.html:1.33 
stratagus/doc/ccl/unittype.html:1.34
--- stratagus/doc/ccl/unittype.html:1.33        Thu Oct  9 07:31:45 2003
+++ stratagus/doc/ccl/unittype.html     Mon Oct 20 20:18:31 2003
@@ -471,7 +471,7 @@
 </dd>
 <dt>random-movement-probablitity</dt>
 <dd>When the unit is idle this is the probability that it will take a
-step in a random direction, in percents. Usefull for netural animals.
+step in a random direction, in percents. Usefull for neutral animals.
 </dd>
 <dt>clicks-to-explode</dt>
 <dd>If this is non-zero, then after that many clicks the unit will commit
@@ -749,7 +749,7 @@
 <h4>Not Used</h4>
 
 <hr>
-Last changed: $Id: unittype.html,v 1.33 2003/10/09 11:31:45 n0body Exp $<br>
+Last changed: $Id: unittype.html,v 1.34 2003/10/21 00:18:31 n0body Exp $<br>
 All trademarks and copyrights on this page are owned by their respective 
owners.
 <address>(c) 2002-2003 by <a href="http://stratagus.org";>
 The Stratagus Project</a></address></body></html>
Index: stratagus/src/clone/ccl_spell.c
diff -u stratagus/src/clone/ccl_spell.c:1.17 
stratagus/src/clone/ccl_spell.c:1.18
--- stratagus/src/clone/ccl_spell.c:1.17        Mon Oct 20 07:08:55 2003
+++ stratagus/src/clone/ccl_spell.c     Mon Oct 20 20:18:31 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: ccl_spell.c,v 1.17 2003/10/20 11:08:55 n0body Exp $
+//     $Id: ccl_spell.c,v 1.18 2003/10/21 00:18:31 n0body Exp $
 //@{
 
 /*----------------------------------------------------------------------------
@@ -122,19 +122,6 @@
                errl("Unsupported fireball tag", value);
            }
        }
-    } else if (gh_eq_p(value, gh_symbol2scm("death-coil"))) {
-       spellaction->CastFunction = CastDeathCoil;
-       while (!gh_null_p(list)) {
-           value = gh_car(list);
-           list = gh_cdr(list);
-           if (gh_eq_p(value, gh_symbol2scm("damage"))) {
-               spellaction->Data.Fireball.Damage = gh_scm2int(gh_car(list));
-               list = gh_cdr(list);
-           } else {
-               errl("Unsupported death-coil tag", value);
-           }
-       }
-
     } else if (gh_eq_p(value, gh_symbol2scm("runes"))) {
        spellaction->CastFunction = CastRunes;
        while (!gh_null_p(list)) {
@@ -158,6 +145,9 @@
            if (gh_eq_p(value, gh_symbol2scm("duration"))) {
                spellaction->Data.Whirlwind.TTL = gh_scm2int(gh_car(list));
                list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("damage"))) {
+               spellaction->Data.Whirlwind.Damage = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
            } else {
                errl("Unsupported runes tag", value);
            }
@@ -621,13 +611,9 @@
     } else if (action->CastFunction == CastSpawnPortal) {
        CLprintf(file, "(spawn-portal portal-type %s)",
            action->Data.SpawnPortal.PortalType->Ident);
-    } else if (action->CastFunction == CastDeathCoil) {
-       CLprintf(file, "(death-coil)");
-       // FIXME: more?
     } else if (action->CastFunction == CastWhirlwind) {
-       CLprintf(file, "(whirlwind duration %d)",
-           action->Data.Whirlwind.TTL);
-       // FIXME: more?
+       CLprintf(file, "(whirlwind duration %d damage %d)",
+           action->Data.Whirlwind.TTL, action->Data.Whirlwind.Damage);
     } 
 }
 
Index: stratagus/src/clone/spells.c
diff -u stratagus/src/clone/spells.c:1.110 stratagus/src/clone/spells.c:1.111
--- stratagus/src/clone/spells.c:1.110  Mon Oct 20 07:08:56 2003
+++ stratagus/src/clone/spells.c        Mon Oct 20 20:18:31 2003
@@ -27,7 +27,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: spells.c,v 1.110 2003/10/20 11:08:56 n0body Exp $
+//     $Id: spells.c,v 1.111 2003/10/21 00:18:31 n0body Exp $
 
 /*
 **     And when we cast our final spell
@@ -204,52 +204,6 @@
 }
 
 /**
-**     Cast death coil.
-**
-**     @param caster   Unit that casts the spell
-**     @param spell    Spell-type pointer
-**     @param target   Target unit that spell is addressed to
-**     @param x        X coord of target spot when/if target does not exist
-**     @param y        Y coord of target spot when/if target does not exist
-**
-**     @return         =!0 if spell should be repeated, 0 if not
-*/
-global int CastDeathCoil(Unit* caster, const SpellType* spell, Unit* target,
-    int x, int y)
-{
-    Missile* mis;
-    int sx;
-    int sy;
-
-    DebugCheck(!caster);
-    DebugCheck(!spell);
-    DebugCheck(!spell->Action);
-//  DebugCheck(target);
-//  DebugCheck(x in range, y in range);
-
-    mis = NULL;
-    sx = caster->X;
-    sy = caster->Y;
-
-    caster->Mana -= spell->ManaCost;
-
-    PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
-    mis = MakeMissile(spell->Missile,
-       sx * TileSizeX + TileSizeX / 2, sy * TileSizeY + TileSizeY / 2,
-       x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2);
-    mis->SourceUnit = caster;
-    mis->Damage = spell->Action->Data.Fireball.Damage;
-    RefsDebugCheck(!caster->Refs || caster->Destroyed);
-    caster->Refs++;
-    if (target) {
-       mis->TargetUnit = target;
-       RefsDebugCheck(!target->Refs || target->Destroyed);
-       target->Refs++;
-    }
-    return 0;
-}
-
-/**
 **     Cast fireball.
 **
 **     @param caster   Unit that casts the spell
@@ -294,7 +248,7 @@
 **     Cast flame shield.
 **
 **     @param caster   Unit that casts the spell
-*      @param spell    Spell-type pointer
+**     @param spell    Spell-type pointer
 **     @param target   Target unit that spell is addressed to
 **     @param x        X coord of target spot when/if target does not exist
 **     @param y        Y coord of target spot when/if target does not exist
@@ -693,6 +647,8 @@
        x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2,
        x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2);
     mis->TTL = spell->Action->Data.Whirlwind.TTL;
+    mis->Damage = spell->Action->Data.Whirlwind.Damage;
+    mis->SourceUnit = caster;
     return 0;
 }
 
Index: stratagus/src/include/missile.h
diff -u stratagus/src/include/missile.h:1.69 
stratagus/src/include/missile.h:1.70
--- stratagus/src/include/missile.h:1.69        Mon Oct 20 07:08:56 2003
+++ stratagus/src/include/missile.h     Mon Oct 20 20:18:31 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: missile.h,v 1.69 2003/10/20 11:08:56 n0body Exp $
+//     $Id: missile.h,v 1.70 2003/10/21 00:18:31 n0body Exp $
 
 #ifndef __MISSILE_H__
 #define __MISSILE_H__
@@ -176,7 +176,18 @@
 **
 **     MissileType::ImpactMissile
 **
-**             Pointer to the impact missile-type.  Used during run time.
+**             Pointer to the impact missile-type. Used during run time.
+**
+**     MissileType::SmokeName
+**
+**             The name of the next (other) missile to generate a trailing 
smoke.  So it
+**             can be used to generate a chain of missiles.
+**             @note Used and should only be used during configuration and
+**             startup.
+**
+**     MissileType::SmokeMissile
+**
+**             Pointer to the smoke missile-type. Used during run time.
 **
 **     MissileType::Sprite
 **
@@ -206,6 +217,14 @@
 **             @note ::TileSizeX%2==0 && ::TileSizeY%2==0 and ::TileSizeX,
 **             ::TileSizeY are currently fixed 32 pixels.
 **
+**     Missile::SourceX Missile::SourceY
+**
+**             Missile original map position in pixels.  To convert a map tile
+**             position to pixel position use: (mapx*::TileSizeX+::TileSizeX/2)
+**             and (mapy*::TileSizeY+::TileSizeY/2)
+**             @note ::TileSizeX%2==0 && ::TileSizeY%2==0 and ::TileSizeX,
+**             ::TileSizeY are currently fixed 32 pixels.
+**
 **     Missile::DX Missile::DY
 **
 **             Missile destination on the map in pixels.  If
@@ -235,7 +254,7 @@
 **     Missile::AnimWait
 **
 **             Animation wait. Used internally by missile actions, to run the
-**             animation in paralel with the rest.
+**             animation in parallel with the rest.
 **
 **     Missile::Wait
 **
@@ -275,24 +294,13 @@
 **             missile lives for ever and the lifetime is handled by
 **             Missile::Type:MissileType::Class
 **
-**     Missile::Controller
-**
-**             A function pointer to the function which controls the missile.
-**             Overwrites Missile::Type:MissileType::Class when !NULL.
-**
-**     Missile::D
+**     Missile::CurrentStep
 **
-**             Delta for Bresenham's line algorithm (point to point missiles).
+**             Movement step. Used for the different trajectories.
 **
-**     Missile::Dx Missile::Dy
+**     Missile::TotalStep
 **
-**             Delta x and y for Bresenham's line algorithm (point to point
-**             missiles).
-**
-**     Missile::Xstep Missile::Ystep
-**
-**             X and y step for Bresenham's line algorithm (point to point
-**             missiles).
+**             Maximum number of step. When CurrentStep >= TotalStep, the 
movement is finished.
 **
 **     Missile::Local
 **
@@ -343,11 +351,6 @@
 /**
 **      Missile-class this defines how a missile-type reacts.
 **
-**      @todo
-**              Here is something double defined, the whirlwind is
-**              ClassWhirlwind and also handled by controler.
-**
-**      FIXME:  We need no class or no controller.
 */
 enum _missile_class_ {
        //      Missile does nothing
@@ -409,6 +412,8 @@
     int                Range;                  /// missile damage range
     char*      ImpactName;             /// impact missile-type name
     MissileType*ImpactMissile;         /// missile produces an impact
+    char*      SmokeName;              /// impact missile-type name
+    MissileType*SmokeMissile;          /// Trailling missile
 
 // --- FILLED UP ---
     Graphic*   Sprite;                 /// missile sprite image
@@ -426,6 +431,8 @@
 
     /// Missile on the map
 struct _missile_ {
+    int                SourceX;                /// Missile Source X
+    int                SourceY;                /// Missile Source Y
     int                X;                      /// missile pixel position
     int                Y;                      /// missile pixel position
     int                DX;                     /// missile pixel destination
@@ -445,16 +452,8 @@
     int                TTL;                    /// time to live (ticks) used 
for spells
 
 // Internal use:
-    int                D;                      /// for point to point missiles
-    int                Dx;                     /// delta x
-    int                Dy;                     /// delta y
-    int                Xstep;                  /// X step
-    int                Ystep;                  /// Y step
-
-    long       Angle;                  /// Angle, for parabolic missiles
-    long       Xl;                     /// internal use. Will be removed later.
-    int                SourceX;                /// Missile Source X
-    int                SourceY;                /// Missile Source Y
+    int                CurrentStep;            /// Current step (0 <= x < 
TotalStep).
+    int                TotalStep;              /// Total step.
 
     unsigned   Local : 1;              /// missile is a local missile
     Missile**  MissileSlot;            /// pointer to missile slot
Index: stratagus/src/include/spells.h
diff -u stratagus/src/include/spells.h:1.31 stratagus/src/include/spells.h:1.32
--- stratagus/src/include/spells.h:1.31 Mon Oct 13 07:21:08 2003
+++ stratagus/src/include/spells.h      Mon Oct 20 20:18:31 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: spells.h,v 1.31 2003/10/13 11:21:08 n0body Exp $
+//     $Id: spells.h,v 1.32 2003/10/21 00:18:31 n0body Exp $
 
 #ifndef __SPELLS_H__
 #define __SPELLS_H__
@@ -150,8 +150,8 @@
        } Runes;
        
        struct {
-           int  TTL;                   /// time to live (ticks)
-           // FIXME: more configurations
+           int TTL;                    /// time to live (ticks)
+           int Damage;                 /// Damage.
        } Whirlwind;
     } Data;
 } SpellActionType;
Index: stratagus/src/missile/ccl_missile.c
diff -u stratagus/src/missile/ccl_missile.c:1.34 
stratagus/src/missile/ccl_missile.c:1.35
--- stratagus/src/missile/ccl_missile.c:1.34    Mon Oct 20 07:08:56 2003
+++ stratagus/src/missile/ccl_missile.c Mon Oct 20 20:18:31 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: ccl_missile.c,v 1.34 2003/10/20 11:08:56 n0body Exp $
+//     $Id: ccl_missile.c,v 1.35 2003/10/21 00:18:31 n0body Exp $
 
 //@{
 
@@ -140,6 +140,9 @@
        } else if (gh_eq_p(value, gh_symbol2scm("impact-missile"))) {
            free(mtype->ImpactName);
            mtype->ImpactName = gh_scm2newstr(gh_car(list), NULL);
+       } else if (gh_eq_p(value, gh_symbol2scm("smoke-missile"))) {
+           free(mtype->ImpactName);
+           mtype->SmokeName = gh_scm2newstr(gh_car(list), NULL);
        } else if (gh_eq_p(value, gh_symbol2scm("can-hit-owner"))) {
            mtype->CanHitOwner = gh_scm2bool(gh_car(list));
        } else if (gh_eq_p(value, gh_symbol2scm("friendly-fire"))) {
@@ -199,13 +202,15 @@
     int y;
     int dx;
     int dy;
+    int sx;
+    int sy;
     Missile* missile;
 
     DebugLevel0Fn("FIXME: not finished\n");
 
     missile = NULL;
     type = NULL;
-    x = dx = y = dy = -1;
+    x = dx = y = dy = sx = sy = -1;
 
     while (!gh_null_p(list)) {
        value = gh_car(list);
@@ -219,14 +224,21 @@
            free(str);
        } else if (gh_eq_p(value, gh_symbol2scm("pos"))) {
            SCM sublist;
-           
+
            sublist = gh_car(list);
            list = gh_cdr(list);
            x = gh_scm2int(gh_car(sublist));
            y = gh_scm2int(gh_cadr(sublist));
+       } else if (gh_eq_p(value, gh_symbol2scm("origin-pos"))) {
+           SCM sublist;
+
+           sublist = gh_car(list);
+           list = gh_cdr(list);
+           sx = gh_scm2int(gh_car(sublist));
+           sy = gh_scm2int(gh_cadr(sublist));
        } else if (gh_eq_p(value, gh_symbol2scm("goal"))) {
            SCM sublist;
-           
+
            sublist = gh_car(list);
            list = gh_cdr(list);
            dx = gh_scm2int(gh_car(sublist));
@@ -238,16 +250,20 @@
                // the way InitMissile() (called from MakeLocalMissile()) 
computes
                // them - it works for creating a missile during a game but 
breaks
                // loading the missile from a file.
-               missile->X = x;
-               missile->Y = y;
-               missile->DX = dx;
-               missile->DY = dy;
+           missile->X = x;
+           missile->Y = y;
+           missile->SourceX = sx;
+           missile->SourceY = sy;
+           missile->DX = dx;
+           missile->DY = dy;
            missile->Local = 1;
        } else if (gh_eq_p(value, gh_symbol2scm("global"))) {
            DebugCheck(!type);
            missile = MakeMissile(type, x, y, dx, dy);
            missile->X = x;
            missile->Y = y;
+           missile->SourceX = sx;
+           missile->SourceY = sy;
            missile->DX = dx;
            missile->DY = dy;
            missile->Local = 0;
@@ -295,21 +311,15 @@
            DebugCheck(!missile);
            missile->TTL = gh_scm2int(gh_car(list));
            list = gh_cdr(list);
-       } else if (gh_eq_p(value, gh_symbol2scm("data"))) {
+       } else if (gh_eq_p(value, gh_symbol2scm("step"))) {
            SCM sublist;
-           
+
+           DebugCheck(!missile);
            sublist = gh_car(list);
            list = gh_cdr(list);
-           missile->D = gh_scm2int(gh_car(sublist));
-           sublist = gh_cdr(sublist);
-           missile->Dx = gh_scm2int(gh_car(sublist));
-           sublist = gh_cdr(sublist);
-           missile->Dy = gh_scm2int(gh_car(sublist));
-           sublist = gh_cdr(sublist);
-           missile->Xstep = gh_scm2int(gh_car(sublist));
-           sublist = gh_cdr(sublist);
-           missile->Ystep = gh_scm2int(gh_car(sublist));
-       }
+           missile->CurrentStep = gh_scm2int(gh_car(sublist));
+           missile->TotalStep = gh_scm2int(gh_cadr(sublist));
+        }
     }
     return SCM_UNSPECIFIED;
 }
Index: stratagus/src/missile/missile.c
diff -u stratagus/src/missile/missile.c:1.97 
stratagus/src/missile/missile.c:1.98
--- stratagus/src/missile/missile.c:1.97        Mon Oct 20 07:08:56 2003
+++ stratagus/src/missile/missile.c     Mon Oct 20 20:18:31 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: missile.c,v 1.97 2003/10/20 11:08:56 n0body Exp $
+//     $Id: missile.c,v 1.98 2003/10/21 00:18:31 n0body Exp $
 
 //@{
 
@@ -59,13 +59,6 @@
 --     Declarations
 ----------------------------------------------------------------------------*/
 
-//     TODO : Remove, configure in ccl.
-//     #define FIREBALL_DAMAGE         20      /// Damage of center fireball
-#define WHIRLWIND_DAMAGE1       4      /// the center of the whirlwind
-#define WHIRLWIND_DAMAGE2       1      /// the periphery of the whirlwind
-//#define RUNE_DAMAGE          50      /// Rune damage
-
-
 /**
 **     Missile class names, used to load/save the missiles.
 */
@@ -87,7 +80,7 @@
     NULL
 };
 
-local void (*MissileClassFunctions[])(Missile*) = {
+local FuncController *MissileClassFunctions[] = {
     MissileActionNone,
     MissileActionPointToPoint,
     MissileActionPointToPointWithHit,
@@ -128,7 +121,7 @@
 local Missile* GlobalMissiles[MAX_MISSILES];   /// all global missiles on map
 local int NumGlobalMissiles;                   /// currently used missiles
 
-local Missile* LocalMissiles[MAX_MISSILES*8];  /// all local missiles on map
+local Missile* LocalMissiles[MAX_MISSILES * 8];        /// all local missiles 
on map
 local int NumLocalMissiles;                    /// currently used missiles
 
 #ifdef DOXYGEN                          // no real code, only for document
@@ -206,7 +199,7 @@
 **     @todo   Don't allocate an array of missile-types, allocate an array
 **             of pointers.
 **
-**     @param ident    Identifier to identify the slot (malloced by caller!).
+**     @param ident    Identifier to identify the slot.
 **
 **     @return         New allocated (zeroed) missile-type pointer.
 */
@@ -236,9 +229,8 @@
     // Rehash.
     //
     for (i = 0; i < NumMissileTypes; ++i) {
-       *(MissileType**)hash_add(MissileTypeHash,MissileTypes[i].Ident) = 
&MissileTypes[i];
+       *(MissileType**)hash_add(MissileTypeHash, MissileTypes[i].Ident) = 
&MissileTypes[i];
     }
-
     mtype->CanHitOwner = 0;            // defaults
     mtype->FriendlyFire = 0;
 
@@ -340,7 +332,7 @@
 **
 **     @return         created missile.
 */
-global Missile* MakeMissile(MissileType* mtype,int sx,int sy,int dx,int dy)
+global Missile* MakeMissile(MissileType* mtype, int sx, int sy, int dx, int dy)
 {
     Missile* missile;
 
@@ -376,7 +368,7 @@
        mtype - MissileTypes _C_ mtype->Ident _C_ sx _C_ sy _C_ dx _C_ dy);
 
     if (!(missile = NewLocalMissile())) {
-       return missile;
+       return NULL;
     }
 
     return InitMissile(missile, mtype, sx, sy, dx, dy);
@@ -425,7 +417,7 @@
     //
     if (missile->Local) {
        DebugCheck(*missile->MissileSlot != missile);
-       temp=LocalMissiles[--NumLocalMissiles];
+       temp = LocalMissiles[--NumLocalMissiles];
        DebugCheck(*temp->MissileSlot != temp);
        temp->MissileSlot = missile->MissileSlot;
        *missile->MissileSlot = temp;
@@ -469,6 +461,8 @@
     int basic_damage;
     int piercing_damage;
 
+    DebugCheck(attacker_stats == NULL);
+    DebugCheck(goal_stats == NULL);
     basic_damage = attacker_stats->BasicDamage + isqrt(xp / 100) * XpDamage;
     piercing_damage = attacker_stats->PiercingDamage;
     if (bloodlust) {
@@ -477,25 +471,10 @@
        DebugLevel3Fn("bloodlust\n");
     }
 
-#if 0
-    damage = basic_damage - goal_stats->Armor;
-    if (damage < 0) {
-       // Use minimum damage
-       if (piercing_damage < 30 && basic_damage < 30) {
-           damage = (piercing_damage + 1) / 2;
-       } else {
-           damage = (piercing_damage + basic_damage - 30) / 2;
-       }
-    } else {
-       damage += piercing_damage;
-       damage -= SyncRand() % ((damage + 2) / 2);
-    }
-#else
     damage = max(basic_damage - goal_stats->Armor, 1) + piercing_damage;
     damage -= SyncRand() % ((damage + 2) / 2);
     DebugCheck(damage < 0);
-#endif
-       
+
     DebugLevel3Fn("\nDamage done [%d] %d %d ->%d\n" _C_ goal_stats->Armor _C_
        basic_damage _C_ piercing_damage _C_ damage);
 
@@ -596,10 +575,6 @@
 
     if (goal) {
        DebugCheck(!goal->Type);        // Target invalid?
-       // Fire to nearest point of the unit!
-       NearestOfUnit(goal, unit->X, unit->Y, &dx, &dy);
-       DebugLevel3Fn("Fire to unit at %d,%d\n" _C_ dx _C_ dy);
-
        //
        //      Moved out of attack range?
        //
@@ -609,7 +584,9 @@
            // FIXME: do something other?
            return;
        }
-
+       // Fire to nearest point of the unit!
+       NearestOfUnit(goal, unit->X, unit->Y, &dx, &dy);
+       DebugLevel3Fn("Fire to unit at %d,%d\n" _C_ dx _C_ dy);
     } else {
        dx = unit->Orders[0].X;
        dy = unit->Orders[0].Y;
@@ -728,7 +705,11 @@
 }
 
 /**
-**     FIXME: docu
+**     Compare Draw level. Used by qsort.
+**
+**     @param v1 : adress of a missile pointer.
+**     @param v2 : adress of a missile pointer.
+**     @return -1 if v1 < v2, 1 else.
 */
 local int MissileDrawLevelCompare(const void* v1, const void* v2)
 {
@@ -741,6 +722,10 @@
     c1 = *(Missile**)v1;
     c2 = *(Missile**)v2;
 
+    DebugCheck(c1 == NULL);
+    DebugCheck(c2 == NULL);
+    DebugCheck(c1->Type == NULL);
+    DebugCheck(c2->Type == NULL);
     if (c1->Type->DrawLevel == c2->Type->DrawLevel) {
        return c1->MissileSlot < c2->MissileSlot ? -1 : 1;
     } else {
@@ -804,6 +789,7 @@
     int nextdir;
 
     DebugCheck(missile == NULL);
+    DebugCheck(missile->Type == NULL);
     if (missile->SpriteFrame < 0) {
        missile->SpriteFrame = -missile->SpriteFrame;
     }
@@ -811,172 +797,81 @@
     missile->SpriteFrame *= missile->Type->NumDirections / 2 + 1;
 
     nextdir = 256 / missile->Type->NumDirections;
+    DebugCheck(nextdir == 0);
     dir = ((DirectionToHeading(dx, dy) + nextdir / 2) & 0xFF) / nextdir;
-    if (dir <= LookingS / nextdir ) {  // north->east->south
+    if (dir <= LookingS / nextdir) {   // north->east->south
        missile->SpriteFrame += dir;
     } else {
        missile->SpriteFrame += 256 / nextdir - dir;
        missile->SpriteFrame = -missile->SpriteFrame;
     }
 }
-
 /**
-**     Handle point to point missile.
-**
-**     @param missile  Missile pointer.
-**
+**     Init the move.
+**     @param missile : missile to initialise for movement.
 **     @return 1 if goal is reached, 0 else.
 */
-local int PointToPointMissile(Missile* missile)
+local int MissileInitMove(Missile* missile)
 {
     int dx;
     int dy;
-    int xstep;
-    int ystep;
-    int i;
 
+    DebugCheck(missile == 0);
     if (!(missile->State & 1)) {
+        dx = missile->DX - missile->X;
+        dy = missile->DY - missile->Y;
+        missile->CurrentStep = 0;
+        missile->TotalStep = 0;
+        if (dx == 0 && dy == 0) {
+            return 1;
+        }
+        MissileNewHeadingFromXY(missile, dx, dy);
        // initialize
-       dy = missile->DY - missile->Y;
-       ystep = 1;
-       if (dy < 0) {
-           dy = -dy;
-           ystep = -1;
-       }
-       dx = missile->DX - missile->X;
-       xstep = 1;
-       if (dx < 0) {
-           dx = -dx;
-           xstep = -1;
-       }
-
-       // FIXME: could be better written
-       if (missile->Type->Class == MissileClassWhirlwind ||
-               missile->Type->Class == MissileClassFlameShield) {
-           // must not call MissileNewHeading nor frame change
-       } else if (missile->Type->Class == MissileClassPointToPointBounce) {
-           missile->DX -= xstep * TileSizeX / 2;
-           missile->DY -= ystep * TileSizeY / 2;
-       } else {
-           MissileNewHeadingFromXY(missile, dx * xstep, dy * ystep);
-       }
-
-       if (dy == 0) {          // horizontal line
-           if (dx == 0) {
-               return 1;
-           }
-       } else if (dx == 0) {   // vertical line
-       } else if (dx < dy) {   // step in vertical direction
-           missile->D = dy - 1;
-           dx += dx;
-           dy += dy;
-       } else if (dx > dy) {   // step in horizontal direction
-           missile->D = dx - 1;
-           dx += dx;
-           dy += dy;
-       }
-
-       missile->Dx = dx;
-       missile->Dy = dy;
-       missile->Xstep = xstep;
-       missile->Ystep = ystep;
-       missile->State++;
-       DebugLevel3Fn("Init: %d,%d, %d,%d, =%d\n" _C_ dx _C_ dy _C_
-           xstep _C_ ystep _C_ missile->D);
-       return 0;
-    } else {
-       // on the way
-       dx = missile->Dx;
-       dy = missile->Dy;
-       xstep = missile->Xstep;
-       ystep = missile->Ystep;
-    }
-
-    //
-    // Move missile
-    //
-    if (dy == 0) {             // horizontal line
-       for (i = 0; i < missile->Type->Speed; ++i) {
-           if (missile->X == missile->DX) {
-               return 1;
-           }
-           missile->X += xstep;
-       }
-       return 0;
-    }
-
-    if (dx == 0) {             // vertical line
-       for (i = 0; i < missile->Type->Speed; ++i) {
-           if (missile->Y == missile->DY) {
-               return 1;
-           }
-           missile->Y += ystep;
-       }
-       return 0;
-    }
-
-    if (dx < dy) {             // step in vertical direction
-       for (i = 0; i < missile->Type->Speed; ++i) {
-           if (missile->Y == missile->DY) {
-               return 1;
-           }
-           missile->Y += ystep;
-           missile->D -= dx;
-           if (missile->D < 0) {
-               missile->D += dy;
-               missile->X += xstep;
-           }
-       }
-       return 0;
-    }
-
-    if (dx > dy) {             // step in horizontal direction
-       for (i = 0; i < missile->Type->Speed; ++i) {
-           if (missile->X == missile->DX) {
-               return 1;
-           }
-           missile->X += xstep;
-           missile->D -= dy;
-           if (missile->D < 0) {
-               missile->D += dx;
-               missile->Y += ystep;
-           }
-       }
-       return 0;
-    }
-                               // diagonal line
-    for (i = 0; i < missile->Type->Speed; ++i) {
-       if (missile->Y == missile->DY) {
-           return 1;
-       }
-       missile->X += xstep;
-       missile->Y += ystep;
-    }
-    return 0;
+        missile->TotalStep = MapDistance(missile->SourceX, missile->SourceY, 
missile->DX, missile->DY);
+        missile->State++;
+        return 0;
+    }
+    DebugCheck(missile->TotalStep == 0);
+    missile->CurrentStep += missile->Type->Speed;
+    if (missile->CurrentStep >= missile->TotalStep)
+    {
+        missile->X = missile->DX;
+        missile->Y = missile->DY;
+        return 1;
+     }
+     return 0;
 }
 
 /**
-**     Calculate parabolic trajectories.
+**     Handle point to point missile.
 **
 **     @param missile  Missile pointer.
-**     @param amplitude    How high can the missile go. This value depends
-**                         on the missile direction and game perspective.
+**
+**     @return 1 if goal is reached, 0 else.
 */
-local int ParabolicCalc(Missile* missile, int amplitude)
+local int PointToPointMissile(Missile* missile)
 {
-    int xmid;
-    long sinu;
-    int thetha;
-
-    missile->Xl -= missile->Xstep;
-    missile->X = (missile->Xl + 500) / 1000;
-
-    xmid = (missile->SourceX + missile->DX) / 2;
-    sinu = (missile->X - xmid) * (missile->X - xmid);
-    thetha = missile->SourceX - xmid;
-    missile->Y = ((missile->Angle * (missile->X - missile->SourceX)) -
-       amplitude * isqrt(-sinu + thetha * thetha) + missile->SourceY * 1000 + 
500 ) / 1000;
-
+    DebugCheck(missile == NULL);
+    if (MissileInitMove(missile) == 1) {
+        return 1;
+    }
+    int xstep;
+    int ystep;
+//    int zstep;
+    DebugCheck(missile->Type == NULL);
+    DebugCheck(missile->TotalStep == 0);
+    xstep = (missile->DX - missile->SourceX) * 1024 / missile->TotalStep;
+    ystep = (missile->DY - missile->SourceY) * 1024 / missile->TotalStep;
+    missile->X = missile->SourceX + xstep * missile->CurrentStep / 1024;
+    missile->Y = missile->SourceY + ystep * missile->CurrentStep / 1024;
+    if (missile->Type->SmokeMissile && missile->CurrentStep) {
+        int x;
+        int y;
+
+        x = missile->X + missile->Type->Width / 2;
+        y = missile->Y + missile->Type->Height / 2;
+        MakeMissile(missile->Type->SmokeMissile, x, y, x, y);
+    }
     return 0;
 }
 
@@ -984,91 +879,51 @@
 **     Calculate parabolic trajectories.
 **
 **     @param missile  Missile pointer.
+**     @return 1 if target is reached.
+**     @return 0 else.
+**     @todo Find good values for ZprojToX et Y
 */
 local int ParabolicMissile(Missile* missile)
 {
-    int i;
-    int sx;
-    int sy;
-
-    if (!(missile->State & 1)) {
-       int dx;
-       int dy;
-       int xstep;
-       int ystep;
-
-       // initialize
-       dy = missile->DY - missile->Y;
-       ystep = 1;
-       if (dy < 0) {
-           dy = -dy;
-           ystep = -1;
-       }
-       dx = missile->DX - missile->X;
-       xstep = 1;
-       if (dx < 0) {
-           dx = -dx;
-           xstep = -1;
-       }
-       if (missile->SourceX - missile->DX != 0) {
-           missile->Angle = (1000 * (missile->SourceY - missile->DY)) / 
-               (missile->SourceX - missile->DX);
-       } else {
-           missile->Angle = 1;
-       }
-       missile->Xl = missile->SourceX * 1000;
-
-       MissileNewHeadingFromXY(missile, dx * xstep, dy * ystep);
-
-       if (dx == 0 && dy == 0) {
-           return 1;
-       }
-
-       missile->Dx = dx;
-       missile->Dy = dy;
-       dx = missile->SourceX - missile->DX;
-       dy = missile->SourceY - missile->DY;
-       missile->Xstep = (1000 * dx) / isqrt(dx * dx + dy * dy);
-       missile->Ystep = ystep;
-       ++missile->State;
-       DebugLevel3Fn("Init: %d,%d\n" _C_ dx _C_ dy);
-       return 0;
-    }
-
-    sx = missile->X;
-    sy = missile->Y;
-
-    //
-    // Move missile
-    //
-    if (missile->Dy == 0) {            // horizontal line
-       for (i = 0; i<missile->Type->Speed; ++i) {
-           if (missile->X == missile->DX) {
-               return 1;
-           }
-           ParabolicCalc(missile, 500);
-       }
-       MissileNewHeadingFromXY(missile, missile->X - sx, missile->Y - sy);
-       return 0;
-    }
+    int orig_x;        // position before moving.
+    int orig_y;        // position before moving.
+    int xstep;
+    int ystep;
+    int K;        // Coefficient of the parabol.
+    int ZprojToX; // Projection of Z axis on axis X.
+    int ZprojToY; // Projection of Z axis on axis Y.
+    int Z; // should be missile->Z later.
 
-    if (missile->Dx == 0) {            // vertical line
-       for (i = 0; i < missile->Type->Speed; ++i) {
-           if (missile->Y == missile->DY) {
-               return 1;
-           }                                   
-           missile->Y += missile->Ystep; //no parabolic missile there.
-       }
-       return 0;
+    DebugCheck(missile == NULL);
+    K = -1024; // Should be initialised by an other method (computed with 
distance...)
+    ZprojToX = 4;
+    ZprojToY = 1024;
+    if (MissileInitMove(missile) == 1) {
+        return 1;
     }
-
-    for (i = 0; i < missile->Type->Speed; ++i) {
-       if (abs(missile->X - missile->DX) <= 1 &&
-               abs(missile->Y - missile->DY) <= 1) {
-           return 1;
-       }
-       ParabolicCalc(missile, 1000);
-       MissileNewHeadingFromXY(missile, missile->X - sx, missile->Y - sy);
+    DebugCheck(missile->Type == NULL);
+    orig_x = missile->X;
+    orig_y = missile->Y;
+    xstep = missile->DX - missile->SourceX;
+    ystep = missile->DY - missile->SourceY;
+    DebugCheck(missile->TotalStep == 0);
+    xstep = xstep * 1000 / missile->TotalStep;
+    ystep = ystep * 1000 / missile->TotalStep;
+    missile->X = missile->SourceX + xstep * missile->CurrentStep / 1000;
+    missile->Y = missile->SourceY + ystep * missile->CurrentStep / 1000;
+    DebugCheck(K == 0);
+    Z = missile->CurrentStep * (missile->TotalStep - missile->CurrentStep) / K;
+// Until Z is used for drawing, modify X and Y.
+    missile->X += Z * ZprojToX / 64;
+    missile->Y += Z * ZprojToY / 64;
+    MissileNewHeadingFromXY(missile, missile->X - orig_x, missile->Y - orig_y);
+    if (missile->Type->SmokeMissile && missile->CurrentStep) {
+        int x;
+        int y;
+
+        x = missile->X + missile->Type->Width / 2;
+        y = missile->Y + missile->Type->Height / 2;
+        MakeMissile(missile->Type->SmokeMissile, x, y, x, y);
     }
     return 0;
 }
@@ -1082,6 +937,9 @@
 */
 local void MissileHitsGoal(const Missile* missile, Unit* goal, int splash)
 {
+    DebugCheck(missile == NULL);
+    DebugCheck(goal == NULL);
+    DebugCheck(missile->Type == NULL);
     if (!missile->Type->CanHitOwner && goal == missile->SourceUnit) {
        return;                         // blizzard cannot hit owner unit
     }
@@ -1090,6 +948,7 @@
        if (missile->Damage) {          // direct damage, spells mostly
            HitUnit(missile->SourceUnit, goal, missile->Damage / splash);
        } else {
+            DebugCheck(missile->SourceUnit == NULL);
            HitUnit(missile->SourceUnit, goal,
                CalculateDamage(missile->SourceUnit->Stats, goal,
                    missile->SourceUnit->Bloodlust, 0) / splash);
@@ -1109,6 +968,7 @@
 */
 local void MissileHitsWall(const Missile* missile, int x, int y, int splash)
 {
+    DebugCheck(missile == NULL);
     if (WallOnMap(x, y)) {
        DebugLevel3Fn("Missile on wall?\n");
        if (HumanWallOnMap(x, y)) {
@@ -1123,6 +983,7 @@
            if (missile->Damage) {      // direct damage, spells mostly
                HitWall(x, y, missile->Damage / splash);
            } else {
+                DebugCheck(missile->SourceUnit == NULL);
                HitWall(x, y,
                    CalculateDamageStats(missile->SourceUnit->Stats,
                        UnitTypeOrcWall->Stats, 0, 0) / splash);
@@ -1146,6 +1007,8 @@
     int n;
     int i;
 
+    DebugCheck(missile == NULL);
+    DebugCheck(missile->Type == NULL);
     if (missile->Type->ImpactSound.Sound) {
        PlayMissileSound(missile, missile->Type->ImpactSound.Sound);
     }
@@ -1181,7 +1044,7 @@
     x /= TileSizeX;
     y /= TileSizeY;
 
-    if (x < 0 || y < 0 || x >= TheMap.Width || y >= TheMap.Height ) {
+    if (x < 0 || y < 0 || x >= TheMap.Width || y >= TheMap.Height) {
        // FIXME: this should handled by caller?
        DebugLevel0Fn("Missile gone outside of map!\n");
        return;                         // outside the map.
@@ -1216,6 +1079,7 @@
     //
     i = missile->Type->Range;
     n = SelectUnits(x - i + 1, y - i + 1, x + i, y + i, table);
+    DebugCheck(missile->SourceUnit == NULL);
     for (i = 0; i < n; ++i) {
        goal = table[i];
        //
@@ -1226,7 +1090,7 @@
            // We are attacking the nearest field of the unit
            if (x < goal->X || y < goal->Y ||
                    x >= goal->X + goal->Type->TileWidth ||
-                   y >= goal->Y + goal->Type->TileHeight ) {
+                   y >= goal->Y + goal->Type->TileHeight) {
                MissileHitsGoal(missile, goal, 2);
            } else {
                MissileHitsGoal(missile, goal, 1);
@@ -1252,32 +1116,60 @@
     }
 }
 
-/*
+/**
 **     Pass to the next frame for animation.
 **
 **     @param missile : missile to animate.
+**     @param sign : 1 for next frame, -1 for previous frame.
+**     @param LongAnimation : 1 if Frame is conditionned by covered distance, 
0 else.
 **
 **     @return 1 if animation is finished, 0 else.
 */
-local int NextMissileFrame(Missile* missile)
+local int NextMissileFrame(Missile* missile, char sign, char LongAnimation)
 {
-    int neg;
-    int AnimationIsFinished;
+    int neg;                 // True for mirroring sprite.
+    int AnimationIsFinished; // returned value.
+    int NumDirections;       // Number of direction of the missile.
 
     DebugCheck(missile == NULL);
+    DebugCheck(missile->Type == NULL);
+    DebugCheck(sign != 1 && sign != -1);
 //
 //     Animate missile, cycle through frames
 //
     neg = 0;
     AnimationIsFinished = 0;
+    NumDirections = missile->Type->NumDirections;
     if (missile->SpriteFrame < 0) {
        neg = 1;
        missile->SpriteFrame = -missile->SpriteFrame;
     }
-    missile->SpriteFrame += missile->Type->NumDirections;
-    if (missile->SpriteFrame >= VideoGraphicFrames(missile->Type->Sprite)) {
-       missile->SpriteFrame -= VideoGraphicFrames(missile->Type->Sprite);
-       AnimationIsFinished = 1;
+    if (LongAnimation) {
+        int totalf;              // Total number of frame (for one direction).
+        int df;                  // Current frame (for one direction).
+        int totalx;              // Total distance to cover.
+        int dx;                  // Covered distance.
+
+        totalx = MapDistance(missile->DX, missile->DY, missile->SourceX, 
missile->SourceY);
+        dx = MapDistance(missile->X, missile->Y, missile->SourceX, 
missile->SourceY);
+        totalf = VideoGraphicFrames(missile->Type->Sprite) / NumDirections;
+        df = missile->SpriteFrame / NumDirections;
+        if ((sign == 1 && dx * totalf <= df * totalx)
+            || (sign == -1 && dx * totalf > df * totalx)) {
+            return AnimationIsFinished;
+        }
+    }
+    missile->SpriteFrame += sign * NumDirections;
+    if (sign > 0) {
+        if (missile->SpriteFrame >= VideoGraphicFrames(missile->Type->Sprite)) 
{
+           missile->SpriteFrame -= VideoGraphicFrames(missile->Type->Sprite);
+           AnimationIsFinished = 1;
+        }
+    } else {
+        if (missile->SpriteFrame < 0) {
+           missile->SpriteFrame += VideoGraphicFrames(missile->Type->Sprite);
+           AnimationIsFinished = 1;
+        }
     }
     if (neg) {
        missile->SpriteFrame = -missile->SpriteFrame;
@@ -1287,7 +1179,7 @@
     return AnimationIsFinished;
 }
 
-/*
+/**
 **     Pass the next frame of the animation.
 **     This animation goes from start to finish ONCE on the way
 **
@@ -1318,8 +1210,8 @@
            } else {
                j = f - i;
            }
-           missile->SpriteFrame = missile->SpriteFrame % 5 +
-               j * 5; // FIXME: frames per row
+           missile->SpriteFrame = missile->SpriteFrame % 
missile->Type->NumDirections +
+               j * missile->Type->NumDirections;
            break;
        }
     }
@@ -1328,7 +1220,7 @@
     }
 }
 
-/*
+/**
 **     Handle all missile actions of global/local missiles.
 **
 **     @param missiles         Table of missiles.
@@ -1338,7 +1230,7 @@
     Missile* missile;
 
     //
-    // NOTE: missiles[??] could be modified!!!
+    // NOTE: missiles[??] could be modified!!! Yes (freed)
     //
     while ((missile = *missiles)) {
        DebugLevel3Fn("Missile %s ttl %d at %d, %d\n" _C_ missile->Type->Ident
@@ -1367,6 +1259,10 @@
 
        MissileClassFunctions[missile->Type->Class](missile);
 
+       if (!missile->TTL) {
+           FreeMissile(missile);
+           continue;
+       }
 
        if (*missiles == missile) {     // Missile not destroyed
            ++missiles;
@@ -1394,8 +1290,11 @@
     int y;
 
     DebugCheck(missile == NULL);
-    x = (missile->X+missile->Type->Width / 2) / TileSizeX;
-    y = (missile->Y+missile->Type->Height / 2) / TileSizeY;    // pixel -> tile
+    DebugCheck(missile->Type == NULL);
+    DebugCheck(TileSizeX <= 0);
+    DebugCheck(TileSizeY <= 0);
+    x = (missile->X + missile->Type->Width / 2) / TileSizeX;
+    y = (missile->Y + missile->Type->Height / 2) / TileSizeY;  // pixel -> tile
 
     DebugLevel3Fn("Missile %p at %d %d\n" _C_ missile _C_ x _C_ y);
 
@@ -1420,6 +1319,7 @@
        frame = tmp;
        tmp = tmp->Next;
     }
+    DebugCheck(frame == NULL);
     return frame->Missile;
 }
 
@@ -1436,8 +1336,9 @@
     char** sp;
     int i;
 
-    CLprintf(file,"\n;;; -----------------------------------------\n");
-    CLprintf(file,";;; MODULE: missile-types $Id: missile.c,v 1.97 2003/10/20 
11:08:56 n0body Exp $\n\n");
+    DebugCheck(file == NULL);
+    CLprintf(file, "\n;;; -----------------------------------------\n");
+    CLprintf(file, ";;; MODULE: missile-types $Id: missile.c,v 1.98 2003/10/21 
00:18:31 n0body Exp $\n\n");
 
     //
     // Original number to internal missile-type name.
@@ -1461,7 +1362,7 @@
        }
        CLprintf(file, " 'size '(%d %d)", mtype->Width, mtype->Height);
        if (mtype->Sprite) {
-           CLprintf(file," 'frames %d", mtype->SpriteFrames);
+           CLprintf(file, " 'frames %d", mtype->SpriteFrames);
        }
        CLprintf(file, "\n  'num-directions %d", mtype->NumDirections);
        CLprintf(file, "\n ");
@@ -1489,6 +1390,9 @@
        if (mtype->ImpactMissile) {
            CLprintf(file, "\n  'impact-missile '%s", 
mtype->ImpactMissile->Ident);
        }
+               if (mtype->SmokeMissile) {
+           CLprintf(file, "\n  'smoke-missile '%s", 
mtype->SmokeMissile->Ident);
+       }
        CLprintf(file, "\n ");
        CLprintf(file, " 'can-hit-owner #%c", mtype->CanHitOwner ? 't' : 'f');
        CLprintf(file, " 'friendly-fire #%c", mtype->FriendlyFire ? 't' : 'f');
@@ -1503,12 +1407,16 @@
 {
     char* s1;
 
-    CLprintf(file, "(missile 'type '%s",missile->Type->Ident);
-    CLprintf(file, " 'pos '(%d %d) 'goal '(%d %d)",
-       missile->X, missile->Y, missile->DX, missile->DY);
-    CLprintf(file," '%s", missile->Local ? "local" : "global");
-    CLprintf(file,"\n  'frame %d 'state %d 'anim-wait %d 'wait %d 'delay %d\n 
",
-       missile->SpriteFrame, missile->State, missile->AnimWait, missile->Wait, 
missile->Delay);
+    DebugCheck(missile == NULL);
+    DebugCheck(missile->Type == NULL);
+    DebugCheck(file == NULL);
+    CLprintf(file, "(missile 'type '%s", missile->Type->Ident);
+    CLprintf(file, " 'pos '(%d %d) 'origin-pos '(%d %d) 'goal '(%d %d)",
+       missile->X, missile->Y, missile->SourceX, missile->SourceY, 
missile->DX, missile->DY);
+    CLprintf(file, " '%s", missile->Local ? "local" : "global");
+    CLprintf(file, "\n  'frame %d 'state %d 'wait %d 'delay %d\n ",
+       missile->SpriteFrame, missile->State, missile->Wait, missile->Delay);
+
     if (missile->SourceUnit) {
        CLprintf(file, " 'source '%s", s1 = UnitReference(missile->SourceUnit));
        free(s1);
@@ -1518,10 +1426,10 @@
        free(s1);
     }
     CLprintf(file, " 'damage %d", missile->Damage);
-    // FIXME: need symbolic names for controller
     CLprintf(file, " 'ttl %d", missile->TTL);
-    CLprintf(file, " 'data '(%d %d %d %d %d)",
-       missile->D, missile->Dx, missile->Dy, missile->Xstep, missile->Ystep);
+    CLprintf(file, " 'step '(%d %d)",
+       missile->CurrentStep,
+       missile->TotalStep);
     CLprintf(file, ")\n");
 }
 
@@ -1534,8 +1442,9 @@
 {
     Missile* const* missiles;
 
+    DebugCheck(file == NULL);
     CLprintf(file,"\n;;; -----------------------------------------\n");
-    CLprintf(file,";;; MODULE: missiles $Id: missile.c,v 1.97 2003/10/20 
11:08:56 n0body Exp $\n\n");
+    CLprintf(file,";;; MODULE: missiles $Id: missile.c,v 1.98 2003/10/21 
00:18:31 n0body Exp $\n\n");
 
     for (missiles = GlobalMissiles; *missiles; ++missiles) {
        SaveMissile(*missiles, file);
@@ -1570,6 +1479,9 @@
        if (mtype->ImpactName) {
            mtype->ImpactMissile = MissileTypeByIdent(mtype->ImpactName);
        }
+       if (mtype->SmokeName) {
+           mtype->SmokeMissile = MissileTypeByIdent(mtype->SmokeName);
+       }
     }
 }
 
@@ -1588,7 +1500,7 @@
        free(mtype->FiredSound.Name);
        free(mtype->ImpactSound.Name);
        free(mtype->ImpactName);
-
+       free(mtype->SmokeName);
        VideoSaveFree(mtype->Sprite);
     }
     free(MissileTypes);
@@ -1648,19 +1560,20 @@
 **
 */
 
-/*
+/**
 **      Missile does nothing
 **     
 **     @param missile  pointer to missile
 */
 void MissileActionNone(Missile* missile)
 {
+    DebugCheck(missile == NULL);
     missile->Wait = missile->Type->Sleep;
     return;//  Busy doing nothing.
 }
 
-/*
-**      Missile flies from x,y to x1,y1 aniation on the way
+/**
+**      Missile flies from x,y to x1,y1 animation on the way
 **     
 **     @param missile  pointer to missile
 */
@@ -1669,13 +1582,13 @@
     missile->Wait = missile->Type->Sleep;
     if (PointToPointMissile(missile)) {
        MissileHit(missile);
-       FreeMissile(missile);
+       missile->TTL = 0;
     } else {
-       NextMissileFrame(missile);
+       NextMissileFrame(missile, 1, 0);
     }
 }
 
-/*
+/**
 **      Missile flies from x,y to x1,y1 showing the first frame
 **     and then shows a hit animation.
 **     
@@ -1683,71 +1596,78 @@
 */
 void MissileActionPointToPointWithHit(Missile* missile)
 {
+    DebugCheck(missile == NULL);
     missile->Wait = missile->Type->Sleep;
     if (PointToPointMissile(missile)) {
-       if (NextMissileFrame(missile)) {
+       if (NextMissileFrame(missile, 1, 0)) {
            MissileHit(missile);
-           FreeMissile(missile);
+           missile->TTL = 0;
        }
     }
 }
        
-/*
+/**
 **      Missile flies from x,y to x1,y1 and stays there for a moment
 **     
 **     @param missile  pointer to missile
 */
 void MissileActionPointToPointCycleOnce(Missile* missile)
 {
+    DebugCheck(missile == NULL);
     missile->Wait = missile->Type->Sleep;
     if (PointToPointMissile(missile)) {
        MissileHit(missile);
-       FreeMissile(missile);
+       missile->TTL = 0;
     } else {
        NextMissileFrameCycle(missile);
     }
 }
 
-/*
+/**
 **      Missile don't move, than disappears
 **     
 **     @param missile  pointer to missile
 */
 void MissileActionStay(Missile* missile)
 {
+    DebugCheck(missile == NULL);
     missile->Wait = missile->Type->Sleep;
-    if (NextMissileFrame(missile)) {
+    if (NextMissileFrame(missile, 1, 0)) {
        MissileHit(missile);
-       FreeMissile(missile);
+       missile->TTL = 0;
     }
 }
 
-/*
-**      Missile flies from x,y to x1,y1 than bounces three times
+/**
+**      Missile flies from x,y to x1,y1 than bounces NumBounces times
 **     
 **     @param missile  pointer to missile
 */
 void MissileActionPointToPointBounce(Missile* missile)
 {
+    DebugCheck(missile == NULL);
     missile->Wait = missile->Type->Sleep;
     if (PointToPointMissile(missile)) {
-       if (missile->State<2*missile->Type->NumBounces) {
+       if (missile->State < 2 * missile->Type->NumBounces) {
+           int sign;
+           int tmp;
            missile->State += 2;
-           missile->DX += missile->Xstep * TileSizeX * 3 / 2;
-           missile->DY += missile->Ystep * TileSizeY * 3 / 2;
+           sign = (tmp = missile->DX - missile->SourceX) ? tmp > 0 ? 1 : -1 : 
0;
+           missile->DX += sign * TileSizeX * 3 / 2;
+           sign = (tmp = missile->DY - missile->SourceY) ? tmp > 0 ? 1 : -1 : 
0;
+           missile->DY += sign * TileSizeY * 3 / 2;
            MissileHit(missile);
            // FIXME: hits to left and right
            // FIXME: reduce damage effects on later impacts
        } else {
-           FreeMissile(missile);
-           missile = NULL;
+           missile->TTL = 0;
        }
     } else {
-       NextMissileFrame(missile);
+       NextMissileFrame(missile, 1, 0);
     }
 }
 
-/*
+/**
 **      Missile doesn't move, it will just cycle once and vanish.
 **     Used for ui missiles (cross shown when you give and order)
 **     
@@ -1755,39 +1675,29 @@
 */
 void MissileActionCycleOnce(Missile* missile)
 {
-    int neg;
+    DebugCheck(missile == NULL);
 
-    neg = 0;
     missile->Wait = missile->Type->Sleep;
-    if (missile->SpriteFrame < 0) {
-       neg = 1;
-       missile->SpriteFrame = -missile->SpriteFrame;
-    }
     switch (missile->State) {
        case 0:
        case 2:
            ++missile->State;
            break;
        case 1:
-           if (++missile->SpriteFrame == 
VideoGraphicFrames(missile->Type->Sprite)) {
-               --missile->SpriteFrame;
+           if (NextMissileFrame(missile, 1, 0)) {
                ++missile->State;
            }
            break;
        case 3:
-           if (!missile->SpriteFrame--) {
+           if (NextMissileFrame(missile, -1, 0)) {
                MissileHit(missile);
-               FreeMissile(missile);
-               missile = NULL;
+               missile->TTL = 0;
            }
            break;
     }
-    if (neg && missile) {
-       missile->SpriteFrame = -missile->SpriteFrame;
-    }
 }
 
-/*
+/**
 **      Missile don't move, than checks the source unit for HP.
 **     
 **     @param missile  pointer to missile
@@ -1796,13 +1706,14 @@
 {
     Unit* unit;
 
+    DebugCheck(missile == NULL);
     unit = missile->SourceUnit;
     missile->Wait = missile->Type->Sleep;
     if (unit->Destroyed || !unit->HP) {
-       FreeMissile(missile);
+       missile->TTL = 0;
        return;
     }
-    if (NextMissileFrame(missile)) {
+    if (NextMissileFrame(missile, 1, 0)) {
        int f;
        MissileType* fire;
 
@@ -1810,8 +1721,7 @@
        f = (100 * unit->HP) / unit->Stats->HitPoints;
        fire = MissileBurningBuilding(f);
        if (!fire) {
-           FreeMissile(missile);
-           missile = NULL;
+           missile->TTL = 0;
            unit->Burning = 0;
        } else {
            if (missile->Type != fire) {
@@ -1825,29 +1735,32 @@
     }
 }
 
-//
-//     Missile shows hit points?
-//
+/**
+**     Missile shows hit points?
+**     @param missile  pointer to missile
+*/
 void MissileActionHit(Missile* missile)
 {
+    DebugCheck(missile == NULL);
     missile->Wait = missile->Type->Sleep;
     if (PointToPointMissile(missile)) {
        MissileHit(missile);
-       FreeMissile(missile);
+       missile->TTL = 0;
     }
 }
 
-/*
-**     Missile flies from x,y to x1,y1 using a parabolic path
+/**
+**      Missile flies from x,y to x1,y1 using a parabolic path
 **     
 **     @param missile  pointer to missile
 */
 void MissileActionParabolic(Missile* missile)
 {
+    DebugCheck(missile == NULL);
     missile->Wait = missile->Type->Sleep;
     if (ParabolicMissile(missile)) {
        MissileHit(missile);
-       FreeMissile(missile);
+       missile->TTL = 0;
     } else {
        NextMissileFrameCycle(missile);
     }
@@ -1932,8 +1845,8 @@
     int y;
 
     DebugCheck(missile == NULL);
-    DebugCheck(TileSizeX == 0);
-    DebugCheck(TileSizeY == 0);
+    DebugCheck(TileSizeX <= 0);
+    DebugCheck(TileSizeY <= 0);
 
     x = missile->X / TileSizeX;
     y = missile->Y / TileSizeY;
@@ -1950,13 +1863,11 @@
        }
     }
 
-    if (!missile->AnimWait) {
-       NextMissileFrame(missile);
+    if (!missile->AnimWait--) {
+       NextMissileFrame(missile, 1, 0);
        missile->AnimWait = missile->Type->Sleep;
-    } else {
-       missile->AnimWait--;
     }
-    missile->Wait=1;
+    missile->Wait = 1;
 }
 
 /**
@@ -1966,9 +1877,6 @@
 */
 global void MissileActionWhirlwind(Missile *missile)
 {
-    Unit *table[UnitMax];
-    int i;
-    int n;
     int x;
     int y;
 
@@ -1977,23 +1885,26 @@
     //
     // Animate, move.
     //
-    if (!missile->AnimWait) {
+    if (!missile->AnimWait--) {
        DebugLevel0Fn("?\n");
-       if (NextMissileFrame(missile)) {
+       if (NextMissileFrame(missile, 1, 0)) {
            missile->SpriteFrame = 0;
            PointToPointMissile(missile);
        }
        missile->AnimWait = missile->Type->Sleep;
-    } else {
-       missile->AnimWait--;
     }
-    missile->Wait=1;
-
+    missile->Wait = 1;
     //
     // Center of the tornado
     //
-    x = (missile->X+TileSizeX/2+missile->Type->Width/2) / TileSizeX;
-    y = (missile->Y+TileSizeY+missile->Type->Height/2) / TileSizeY;
+    x = (missile->X + TileSizeX / 2 + missile->Type->Width / 2) / TileSizeX;
+    y = (missile->Y + TileSizeY + missile->Type->Height / 2) / TileSizeY;
+
+#if 0
+    Unit *table[UnitMax];
+    int i;
+    int n;
+
     //
     // Every 4 cycles 4 points damage in tornado center
     //
@@ -2020,7 +1931,12 @@
     }
     DebugLevel0Fn( "Whirlwind: %d, %d, TTL: %d state: %d\n" _C_
            missile->X _C_ missile->Y _C_ missile->TTL _C_ missile->State);
+#else
+    if (!(missile->TTL % CYCLES_PER_SECOND / 10)) {
+        MissileHit(missile);
+     }
 
+#endif
     //
     // Changes direction every 3 seconds (approx.)
     //
@@ -2035,9 +1951,11 @@
        } while (nx < 0 && ny < 0 && nx >= TheMap.Width && ny >= TheMap.Height);
        missile->DX = nx * TileSizeX + TileSizeX / 2;
        missile->DY = ny * TileSizeY + TileSizeY / 2;
-       missile->State=0;
+       missile->SourceX = missile->X;
+       missile->SourceY = missile->Y;
+       missile->State = 0;
        DebugLevel0Fn( "Whirlwind new direction: %d, %d, TTL: %d\n" _C_
-               missile->X _C_ missile->Y _C_ missile->TTL );
+               missile->DX _C_ missile->DY _C_ missile->TTL );
     }
 }
 
@@ -2056,13 +1974,8 @@
     DebugCheck(missile == NULL);
     missile->Wait = missile->Type->Sleep;
     if (PointToPointMissile(missile)) {
-       //
-       //  missile has not reached target unit/spot
-       //
-       if (!(missile->X == missile->DX && missile->Y == missile->DY)) {
-           return ;
-       }
        source = missile->SourceUnit;
+       DebugCheck(source == NULL);
        if (source->Destroyed) {
            return ;
        }
@@ -2117,7 +2030,7 @@
                }
            }
        }
-       FreeMissile(missile);
+       missile->TTL = 0;
     }
 }
 
Index: stratagus/src/network/lowlevel.c
diff -u stratagus/src/network/lowlevel.c:1.39 
stratagus/src/network/lowlevel.c:1.40
--- stratagus/src/network/lowlevel.c:1.39       Fri Oct 17 20:19:48 2003
+++ stratagus/src/network/lowlevel.c    Mon Oct 20 20:18:31 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: lowlevel.c,v 1.39 2003/10/18 00:19:48 jsalmon3 Exp $
+//     $Id: lowlevel.c,v 1.40 2003/10/21 00:18:31 n0body Exp $
 
 //@{
 
@@ -298,7 +298,7 @@
        wsError = WSAIoctl(sock, SIO_GET_INTERFACE_LIST, NULL, 0, &localAddr,
            sizeof(localAddr), &bytesReturned, NULL, NULL);
        if (wsError == SOCKET_ERROR) {
-           DebugLevel0Fn("SIOCGIFCONF:WSAIoctl(SIO_GET_INTERFACE_LIST) - errno 
%ld\n" _C_
+           DebugLevel0Fn("SIOCGIFCONF:WSAIoctl(SIO_GET_INTERFACE_LIST) - errno 
%d\n" _C_
                WSAGetLastError());
        }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]