From c9643280edd9232041e9bafe996659583a1e8165 Mon Sep 17 00:00:00 2001
From: cade <>
Date: Sun, 25 Jun 2000 23:03:13 +0000
Subject: [PATCH] *** empty log message ***

---
 src/action/action_spellcast.cpp | 168 ++++++++++++++++++++++++++++++++
 1 file changed, 168 insertions(+)
 create mode 100644 src/action/action_spellcast.cpp

diff --git a/src/action/action_spellcast.cpp b/src/action/action_spellcast.cpp
new file mode 100644
index 000000000..8c6327ec6
--- /dev/null
+++ b/src/action/action_spellcast.cpp
@@ -0,0 +1,168 @@
+//   ___________		     _________		      _____  __
+//   \_	  _____/______   ____   ____ \_   ___ \____________ _/ ____\/  |_
+//    |    __) \_  __ \_/ __ \_/ __ \/    \  \/\_  __ \__  \\   __\\   __\ 
+//    |     \   |  | \/\  ___/\  ___/\     \____|  | \// __ \|  |   |  |
+//    \___  /   |__|    \___  >\___  >\______  /|__|  (____  /__|   |__|
+//        \/		            \/	   \/	       \/		         \/
+//  ______________________                           ______________________
+//			  T H E   W A R   B E G I N S
+//	   FreeCraft - A free fantasy real time strategy game engine
+//
+/**@name action_spellcast.c	-	The spell cast action. */
+/*
+**	(c) Copyright 1998-2000 by Vladi Belperchinov-Shabanski
+**
+**	$Id$
+*/
+
+/*
+** This is inherited from action_attack.c, actually spell casting will
+** be considered a `special' case attack action... //Vladi
+*/
+
+//@{
+
+/*----------------------------------------------------------------------------
+--	Includes
+----------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "freecraft.h"
+#include "video.h"
+#include "sound_id.h"
+#include "unitsound.h"
+#include "unittype.h"
+#include "player.h"
+#include "unit.h"
+#include "missile.h"
+#include "actions.h"
+#include "sound.h"
+#include "tileset.h"
+#include "map.h"
+#include "spells.h"
+
+/*----------------------------------------------------------------------------
+--	Functions
+----------------------------------------------------------------------------*/
+
+/**
+**	Animate unit spell cast (it is attack really)!
+**
+**	@param unit	Unit, for that the spell cast/attack animation is played.
+*/
+global int AnimateActionSpellCast(Unit* unit)
+{
+    int flags;
+    flags=UnitShowAnimation(unit,unit->Type->Animations->Attack);
+
+    if( unit->Type->Animations ) {
+	    DebugCheck( !unit->Type->Animations->Attack );
+      
+      if( (flags & AnimationSound) )
+  	    PlayUnitSound(unit,VoiceAttacking); // FIXME: ?????
+  
+      if( flags & AnimationMissile ) // FIXME: ?????
+        FireMissile(unit); /* we should not get here ?? */
+    }
+    return 0;
+}
+
+/**
+**	Handle moving to the target.
+**
+**	@param unit	Unit, for that the spell cast is handled.
+*/
+local void MoveToTarget(Unit* unit)
+{
+	Unit* goal;
+	int err;
+
+        err = HandleActionMove(unit);
+	if ( !unit->Reset ) return;    
+	// when reached HandleActionMove changes unit action
+	unit->Command.Action = UnitActionSpellCast;
+	
+	goal = unit->Command.Data.Move.Goal;
+	if( goal && MapDistanceToUnit(unit->X,unit->Y,goal) 
+	       <= unit->Command.Data.Move.Range ) 
+	{ // there is goal and it is in range
+	    unit->State=0;
+  	    UnitHeadingFromDeltaXY(unit,goal->X - unit->X,
+	                                goal->Y - unit->Y);
+	    unit->SubAction = 1; // cast the spell
+	    return;
+	} else 
+	if( !goal && MapDistance(unit->X,unit->Y,
+	             unit->Command.Data.Move.DX,unit->Command.Data.Move.DY)
+		  <= unit->Command.Data.Move.Range ) 
+	{ // there is no goal and target spot is in range
+	    unit->State=0;
+	    UnitHeadingFromDeltaXY(unit,
+	           unit->Command.Data.Move.DX - unit->X,
+		   unit->Command.Data.Move.DY - unit->Y);
+	    unit->SubAction = 1; // cast the spell
+	    return;
+	} else 
+	if( err ) 
+	{ // goal/spot out of range -- move to target
+   	    // FIXME: Should handle new return codes (err) here (for Fabrice)
+	    unit->State=0;
+	    unit->SubAction=0;
+	}
+	DebugCheck( unit->Type->Vanishes || unit->Destroyed );
+}
+
+/**
+**	Unit casts a spell!
+**
+**	@param unit	Unit, for that the spell cast is handled.
+*/
+global void HandleActionSpellCast(Unit* unit)
+{
+    int repeat = 0; // repeat spell on next pass? (defaults to `no')
+    
+    DebugLevel3(__FUNCTION__": SpellCast %Zd\n",UnitNumber(unit));
+
+    switch( unit->SubAction ) {
+	
+	case 0: // Move to the target.
+	    MoveToTarget(unit);
+	    break;
+
+	case 1: // Cast spell on the target.
+		{
+		const SpellType* spell = SpellTypeById( unit->Command.Data.Move.SpellId );
+		if ( unit->Mana < spell->ManaCost )
+		  {
+		  SetMessage( "%s: not enough mana to cast spell: %s", 
+                              unit->Type->Name, spell->Ident );
+		  repeat = 0;	      
+		  }
+		else
+		  {
+		  UnitShowAnimation(unit,unit->Type->Animations->Attack);
+		  if ( !unit->Reset ) return;
+		  repeat = SpellCast(unit->Command.Data.Move.SpellId, 
+				    unit, 
+				    unit->Command.Data.Move.Goal, 
+				    unit->Command.Data.Move.DX,
+				    unit->Command.Data.Move.DY );
+		  }   
+		  if ( !repeat ) {
+		     unit->Command.Action=UnitActionStill;
+		     unit->SubAction=0;
+		     unit->State=0;
+		     if ( unit->Command.Data.Move.Goal )
+		        unit->Command.Data.Move.Goal->Refs--;
+		  }
+		}
+	    break;
+	    
+        default:
+	        unit->SubAction = 0; // Move to the target
+    }
+}
+
+//@}