/* =========================================================================== ARX FATALIS GPL Source Code Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company. This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code'). Arx Fatalis Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Arx Fatalis Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Arx Fatalis Source Code. If not, see . In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ /////////////////////////////////////////////////////////////////////////////// // // ARX_Spells.cpp // ARX Spells Management & Projectiles // // Copyright (c) 1999-2000 ARKANE Studios SA. All rights reserved // /////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include "danae.h" #include #include #include #include #include #include #include #include "ARX_Menu2.h" #include "ARX_Minimap.h" #include "ARX_Scene.h" #include #include #include "ARX_SpellFX.h" #include #include #define _CRTDBG_MAP_ALLOC #include void MakeSpCol(); extern long WILLRETURNTOCOMBATMODE; extern CMenuConfig *pMenuConfig; extern long TRUE_PLAYER_MOUSELOOK_ON; long passwall=0; long WILLRETURNTOFREELOOK = 0; long GLOBAL_MAGIC_MODE=1; bool bPrecastSpell = false; extern char LAST_FAILED_SEQUENCE[128]; enum ARX_SPELLS_RuneDirection { AUP, AUPRIGHT, ARIGHT, ADOWNRIGHT, ADOWN, ADOWNLEFT, ALEFT, AUPLEFT }; long sp_arm=0; long cur_arm=0; long cur_sos=0; void ApplyPasswall(); void ApplySPArm(); void ApplySPuw(); void ApplySPRf(); void ApplySPMax(); void ApplySPWep(); void ApplySPBow(); void ApplyCurPNux(); void ApplyCurMr(); void ApplyCurSOS(); extern long FistParticles; extern long ParticleCount; extern long sp_max; short uw_mode=0; short uw_mode_pos=0; extern long MAGICMODE; extern INTERACTIVE_OBJ * CURRENT_TORCH; extern float GLOBAL_SLOWDOWN; extern long BH_MODE; extern void EERIE_OBJECT_MakeBH(EERIE_3DOBJ * obj); extern void ARX_SPSound(); extern float sp_max_y[64]; extern COLORREF sp_max_col[64]; extern char sp_max_ch[64]; extern long sp_max_nb; long cur_mega=0; float sp_max_start = 0; long sp_wep=0; extern long INTERNATIONAL_MODE; extern bool bRenderInCursorMode; bool bOldLookToggle; extern float SLID_START; void EERIE_OBJECT_SetBHMode() { if (BH_MODE) BH_MODE=0; else { BH_MODE=1; MakeCoolFx(&player.pos); MakeSpCol(); strcpy(sp_max_ch,"!!!_Super-Deformed_!!!"); sp_max_nb=strlen(sp_max_ch); sp_max_start=ARX_TIME_Get(); } } typedef struct { short SlotDir; } Scan; typedef struct { unsigned long starttime; EERIE_3D lastpos; short lasttim; short duration; short symbol; char sequence[32]; char cPosStartX; char cPosStartY; } SYMBOL_DRAW; extern long NO_TEXT_AT_ALL; extern bool FrustrumsClipSphere(EERIE_FRUSTRUM_DATA * frustrums,EERIE_SPHERE * sphere); extern bool bGToggleCombatModeWithKey; void ARX_INTERFACE_Combat_Mode(long i); float ARX_SPELLS_GetManaCost(long _lNumSpell,long _lNumSpellTab); //----------------------------------------------------------------------------- ///////////////Spell Interpretation SPELL spells[MAX_SPELLS]; short ARX_FLARES_broken(1); long CurrSlot(1); long LastSlot(0); long CurrPoint(0); long cur_mx=0; long cur_pnux=0; long cur_pom=0; long cur_rf=0; long cur_mr=0; long cur_sm=0; long cur_bh=0; float TELEPORT(0.0F); float LASTTELEPORT(0.0F); long snip=0; EERIE_S2D Lm; static const long MAX_POINTS(200); static EERIE_S2D plist[MAX_POINTS]; static char SpellMoves[MAX_POINTS]; long SpellSymbol[MAX_SPELL_SYMBOLS]; long CurrSpellSymbol=0; Scan spell[MAX_SLOT + 1]; long lMaxSymbolDrawSizeX; long lMaxSymbolDrawSizeY; unsigned char ucFlick=0; BOOL GetSpellPosition(EERIE_3D * pos,long i) { switch (spells[i].type) { //********************************************************************************************* // LEVEL 1 SPELLS ----------------------------------------------------------------------------- case SPELL_MAGIC_SIGHT: // Launching MAGIC_SIGHT break; //---------------------------------------------------------------------------------------------- case SPELL_MAGIC_MISSILE: // Launching MAGIC_MISSILE break; //---------------------------------------------------------------------------------------------- case SPELL_IGNIT:// Launching IGNIT break; //--------------------------------------------------------------------------------------------- case SPELL_DOUSE:// Launching DOUSE break; //--------------------------------------------------------------------------------------------- case SPELL_ACTIVATE_PORTAL:// Launching ACTIVATE_PORTAL break; //************************************************************************************************* // LEVEL 2 SPELLS ----------------------------------------------------------------------------- case SPELL_HEAL:// Launching HEAL break; //--------------------------------------------------------------------------------------------- case SPELL_DETECT_TRAP:// Launching DETECT_TRAP break; //--------------------------------------------------------------------------------------------- case SPELL_ARMOR:// Launching ARMOR if (ValidIONum(spells[i].target)) { Vector_Copy(pos,&inter.iobj[spells[i].target]->pos); return TRUE; } break; //------------------------------------------------------------------------------------------------ case SPELL_LOWER_ARMOR:// Launching LOWER_ARMOR if (ValidIONum(spells[i].target)) { Vector_Copy(pos,&inter.iobj[spells[i].target]->pos); return TRUE; } break; //------------------------------------------------------------------------------------------------ case SPELL_HARM:// Launching HARM break; //********************************************************************************************** // LEVEL 3 SPELLS ----------------------------------------------------------------------------- case SPELL_SPEED:// Launching SPEED if (ValidIONum(spells[i].target)) { Vector_Copy(pos,&inter.iobj[spells[i].target]->pos); return TRUE; } break; //-------------------------------------------------------------------------------------------------- case SPELL_DISPELL_ILLUSION:// Launching DISPELL_ILLUSION (REVEAL) break; //---------------------------------------------------------------------------------------------- case SPELL_FIREBALL:// Launching FIREBALL break; //------------------------------------------------------------------------------------------------- case SPELL_CREATE_FOOD:// Launching CREATE_FOOD break; //---------------------------------------------------------------------------------------------- case SPELL_ICE_PROJECTILE:// Launching ICE_PROJECTILE break; //*********************************************************************************************** // LEVEL 4 SPELLS ----------------------------------------------------------------------------- case SPELL_BLESS:// Launching BLESS if (ValidIONum(spells[i].target)) { Vector_Copy(pos,&inter.iobj[spells[i].target]->pos); return TRUE; } break; //----------------------------------------------------------------------------------------------- case SPELL_DISPELL_FIELD:// Launching DISPELL_FIELD break; //----------------------------------------------------------------------------------------------- case SPELL_FIRE_PROTECTION:// Launching FIRE_PROTECTION if (ValidIONum(spells[i].target)) { Vector_Copy(pos,&inter.iobj[spells[i].target]->pos); return TRUE; } break; //---------------------------------------------------------------------------------------------- case SPELL_COLD_PROTECTION:// Launching COLD_PROTECTION if (ValidIONum(spells[i].target)) { Vector_Copy(pos,&inter.iobj[spells[i].target]->pos); return TRUE; } break; //---------------------------------------------------------------------------------------------- case SPELL_TELEKINESIS:// Launching TELEKINESIS break; //----------------------------------------------------------------------------------------------- case SPELL_CURSE:// Launching CURSE if (ValidIONum(spells[i].target)) { Vector_Copy(pos,&inter.iobj[spells[i].target]->pos); return TRUE; } break; //********************************************************************* // LEVEL 5 SPELLS ----------------------------------------------------------------------------- case SPELL_RUNE_OF_GUARDING: break; //---------------------------------------------------------------------------- case SPELL_LEVITATE: break; //---------------------------------------------------------------------------- case SPELL_CURE_POISON: break; //---------------------------------------------------------------------------- case SPELL_REPEL_UNDEAD: break; //---------------------------------------------------------------------------- case SPELL_POISON_PROJECTILE: break; //*************************************************************************** // LEVEL 6 ----------------------------------------------------------------------------- case SPELL_RISE_DEAD: break; //---------------------------------------------------------------------------- case SPELL_PARALYSE: if (ValidIONum(spells[i].target)) { Vector_Copy(pos,&inter.iobj[spells[i].target]->pos); return TRUE; } break; //---------------------------------------------------------------------------- case SPELL_CREATE_FIELD: break; //---------------------------------------------------------------------------- case SPELL_DISARM_TRAP: break; //---------------------------------------------------------------------------- case SPELL_SLOW_DOWN: if (ValidIONum(spells[i].target)) { Vector_Copy(pos,&inter.iobj[spells[i].target]->pos); return TRUE; } break; //**************************************************************************************** // LEVEL 7 SPELLS ----------------------------------------------------------------------------- case SPELL_FLYING_EYE: { Vector_Copy(pos,&eyeball.pos); return TRUE; } break; //---------------------------------------------------------------------------- case SPELL_FIRE_FIELD: CSpellFx *pCSpellFX; pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { CFireField *pFireField = (CFireField *) pCSpellFX; Vector_Copy(pos,&pFireField->pos); return TRUE; } break; //---------------------------------------------------------------------------- case SPELL_ICE_FIELD: break; //---------------------------------------------------------------------------- case SPELL_LIGHTNING_STRIKE: break; //---------------------------------------------------------------------------- case SPELL_CONFUSE: if (ValidIONum(spells[i].target)) { Vector_Copy(pos,&inter.iobj[spells[i].target]->pos); return TRUE; } break; //********************************************************************************* // LEVEL 8 SPELLS ----------------------------------------------------------------------------- case SPELL_INVISIBILITY: if (ValidIONum(spells[i].target)) { Vector_Copy(pos,&inter.iobj[spells[i].target]->pos); return TRUE; } break; //---------------------------------------------------------------------------- case SPELL_MANA_DRAIN: if (ValidIONum(spells[i].target)) { Vector_Copy(pos,&inter.iobj[spells[i].target]->pos); return TRUE; } break; //---------------------------------------------------------------------------- case SPELL_EXPLOSION: break; //---------------------------------------------------------------------------- case SPELL_ENCHANT_WEAPON: break; //---------------------------------------------------------------------------- case SPELL_LIFE_DRAIN: if (ValidIONum(spells[i].target)) { Vector_Copy(pos,&inter.iobj[spells[i].target]->pos); return TRUE; } break; //***************************************************************************************** // LEVEL 9 SPELLS ----------------------------------------------------------------------------- case SPELL_SUMMON_CREATURE: break; //---------------------------------------------------------------------------- case SPELL_NEGATE_MAGIC: break; //---------------------------------------------------------------------------- case SPELL_INCINERATE: if (ValidIONum(spells[i].target)) { Vector_Copy(pos,&inter.iobj[spells[i].target]->pos); return TRUE; } break; //---------------------------------------------------------------------------- case SPELL_MASS_PARALYSE: break; //---------------------------------------------------------------------------- //******************************************************************************************** // LEVEL 10 SPELLS ----------------------------------------------------------------------------- case SPELL_MASS_LIGHTNING_STRIKE: break; //---------------------------------------------------------------------------- case SPELL_CONTROL_TARGET: break; //---------------------------------------------------------------------------- case SPELL_FREEZE_TIME: break; //---------------------------------------------------------------------------- case SPELL_MASS_INCINERATE: break; //---------------------------------------------------------------------------- case SPELL_TELEPORT: break; //---------------------------------------------------------------------------- } if (ValidIONum(spells[i].caster)) { Vector_Copy(pos,&inter.iobj[spells[i].caster]->pos); return TRUE; } return FALSE; } void LaunchAntiMagicField(EERIE_3D * pos,long ident) { for (long n=0;n= spells[n].caster_level) && (n!=ident) ) { EERIE_3D pos; GetSpellPosition(&pos,n); if (EEDistance3D(&pos,&inter.iobj[spells[ident].caster]->pos)<600.f) { if (spells[n].type==SPELL_CREATE_FIELD) { if ((spells[ident].caster==0) && (spells[n].caster==0)) spells[n].tolive=0; } else spells[n].tolive=0; } } } } //----------------------------------------------------------------------------- void ARX_SPELLS_AddSpellOn(const long &caster, const long &spell) { if (caster < 0 || spell < 0 || !inter.iobj[caster]) return; INTERACTIVE_OBJ *io = inter.iobj[caster]; void *ptr; ptr = realloc(io->spells_on, sizeof(long) * (io->nb_spells_on + 1)); if (!ptr) return; io->spells_on = (long *)ptr; io->spells_on[io->nb_spells_on] = spell; io->nb_spells_on++; } //----------------------------------------------------------------------------- long ARX_SPELLS_GetSpellOn(const INTERACTIVE_OBJ *io, const long &spellid) { if (!io) return -1; for (long i(0); i < io->nb_spells_on; i++) { if ( (spells[io->spells_on[i]].type == spellid) && (spells[io->spells_on[i]].exist) ) return io->spells_on[i]; } return -1; } //----------------------------------------------------------------------------- void ARX_SPELLS_RemoveSpellOn(const long &caster, const long &spell) { if (caster < 0 || spell < 0) return; INTERACTIVE_OBJ *io = inter.iobj[caster]; if (!io || !io->nb_spells_on) return; if (io->nb_spells_on == 1) { free(io->spells_on); io->spells_on = NULL; io->nb_spells_on = 0; return; } long i(0); for (; i < io->nb_spells_on; i++) if (io->spells_on[i] == spell) break; if ( i >= io->nb_spells_on) return; io->nb_spells_on--; memcpy(&io->spells_on[i], &io->spells_on[i + 1], sizeof(long) * (io->nb_spells_on - i)); io->spells_on = (long *)realloc(io->spells_on, sizeof(long) * io->nb_spells_on); } void ARX_SPELLS_RemoveMultiSpellOn(long spell_id) { for (long i=0;ispells_on), io->spells_on = NULL, io->nb_spells_on = 0; } //----------------------------------------------------------------------------- void ARX_SPELLS_RequestSymbolDraw(INTERACTIVE_OBJ *io, const char *name, const float &duration) { long symb(-1); char sequence[32]; int iPosX = 0; int iPosY = 0; if (!strcmp(name, "AAM")) symb = SYMBOL_AAM, iPosX = 0, iPosY = 2, strcpy(sequence, "6666"); else if (!strcmp(name, "CETRIUS")) symb = SYMBOL_CETRIUS, iPosX = 0, iPosY = 1, strcpy(sequence, "33388886666"); else if (!strcmp(name, "COMUNICATUM")) symb = SYMBOL_COMUNICATUM, iPosX = 0, iPosY = 0, strcpy(sequence, "6666622244442226666"); else if (!strcmp(name, "COSUM")) symb = SYMBOL_COSUM, iPosX = 0, iPosY = 2, strcpy(sequence, "66666222244448888"); else if (!strcmp(name, "FOLGORA")) symb = SYMBOL_FOLGORA, iPosX = 0, iPosY = 3, strcpy(sequence, "99993333"); else if (!strcmp(name, "FRIDD")) symb = SYMBOL_FRIDD, iPosX = 0, iPosY = 4, strcpy(sequence, "888886662222"); else if (!strcmp(name, "KAOM")) symb = SYMBOL_KAOM, iPosX = 3, iPosY = 0, strcpy(sequence, "44122366"); else if (!strcmp(name, "MEGA")) symb = SYMBOL_MEGA, iPosX = 2, iPosY = 4, strcpy(sequence, "88888"); else if (!strcmp(name, "MORTE")) symb = SYMBOL_MORTE, iPosX = 0, iPosY = 2, strcpy(sequence, "66666222"); else if (!strcmp(name, "MOVIS")) symb = SYMBOL_MOVIS, iPosX = 0, iPosY = 0, strcpy(sequence, "666611116666"); else if (!strcmp(name, "NHI")) symb = SYMBOL_NHI, iPosX = 4, iPosY = 2, strcpy(sequence, "4444"); else if (!strcmp(name, "RHAA")) symb = SYMBOL_RHAA, iPosX = 2, iPosY = 0, strcpy(sequence, "22222"); else if (!strcmp(name, "SPACIUM")) symb = SYMBOL_SPACIUM, iPosX = 4, iPosY = 0, strcpy(sequence, "44444222266688"); else if (!strcmp(name, "STREGUM")) symb = SYMBOL_STREGUM, iPosX = 0, iPosY = 4, strcpy(sequence, "8888833338888"); else if (!strcmp(name, "TAAR")) symb = SYMBOL_TAAR, iPosX = 0, iPosY = 1, strcpy(sequence, "666222666"); else if (!strcmp(name, "TEMPUS")) symb = SYMBOL_TEMPUS, iPosX = 0, iPosY = 4, strcpy(sequence, "88886662226668866"); else if (!strcmp(name, "TERA")) symb = SYMBOL_TERA, iPosX = 0, iPosY = 3, strcpy(sequence, "99922266"); else if (!strcmp(name, "VISTA")) symb = SYMBOL_VISTA, iPosX = 1, iPosY = 0, strcpy(sequence, "333111"); else if (!strcmp(name, "VITAE")) symb = SYMBOL_VITAE, iPosX = 0, iPosY = 2, strcpy(sequence, "66666888"); else if (!strcmp(name, "YOK")) symb = SYMBOL_YOK, iPosX = 0, iPosY = 0, strcpy(sequence, "222226666888"); else if (!strcmp(name, "AKBAA")) symb = SYMBOL_AKBAA, iPosX = 0, iPosY = 0, strcpy(sequence, "22666772222"); if (symb == -1) return; io->symboldraw = realloc(io->symboldraw, sizeof(SYMBOL_DRAW)); if (!io->symboldraw) return; SYMBOL_DRAW *sd = (SYMBOL_DRAW *)io->symboldraw; sd->duration = duration < 1.0F ? 1 : (short)(long)duration; strcpy(sd->sequence, sequence); sd->starttime = ARXTimeUL(); sd->lasttim = 0; sd->symbol = (short)symb; sd->lastpos.x = io->pos.x - EEsin(DEG2RAD(MAKEANGLE(io->angle.b - 45.0F + iPosX*2))) * 60.0F; sd->lastpos.y = io->pos.y - 120.0F - iPosY*5; sd->lastpos.z = io->pos.z + EEcos(DEG2RAD(MAKEANGLE(io->angle.b - 45.0F + iPosX*2))) * 60.0F; ARX_CHECK_CHAR(iPosX); ARX_CHECK_CHAR(iPosY); sd->cPosStartX = ARX_CLEAN_WARN_CAST_CHAR(iPosX); sd->cPosStartY = ARX_CLEAN_WARN_CAST_CHAR(iPosY); io->GameFlags &= ~GFLAG_INVISIBILITY; } //----------------------------------------------------------------------------- void ARX_SPELLS_RequestSymbolDraw2(INTERACTIVE_OBJ *io, const long &symb, const float &duration) { char sequence[32]; int iPosX = 0; int iPosY = 0; long _symb; switch (symb) { case RUNE_AAM : _symb = SYMBOL_AAM; iPosX = 0; iPosY = 2; strcpy(sequence, "6666"); break; case RUNE_CETRIUS: _symb = SYMBOL_CETRIUS, iPosX = 0, iPosY = 1, strcpy(sequence, "33388886666"); break; case RUNE_COMUNICATUM: _symb = SYMBOL_COMUNICATUM, iPosX = 0, iPosY = 0, strcpy(sequence, "6666622244442226666"); break; case RUNE_COSUM: _symb = SYMBOL_COSUM, iPosX = 0, iPosY = 2, strcpy(sequence, "66666222244448888"); break; case RUNE_FOLGORA: _symb = SYMBOL_FOLGORA, iPosX = 0, iPosY = 3, strcpy(sequence, "99993333"); break; case RUNE_FRIDD: _symb = SYMBOL_FRIDD, iPosX = 0, iPosY = 4, strcpy(sequence, "888886662222"); break; case RUNE_KAOM: _symb = SYMBOL_KAOM, iPosX = 3, iPosY = 0, strcpy(sequence, "44122366"); break; case RUNE_MEGA: _symb = SYMBOL_MEGA, iPosX = 2, iPosY = 4, strcpy(sequence, "88888"); break; case RUNE_MORTE: _symb = SYMBOL_MORTE, iPosX = 0, iPosY = 2, strcpy(sequence, "66666222"); break; case RUNE_MOVIS: _symb = SYMBOL_MOVIS, iPosX = 0, iPosY = 0, strcpy(sequence, "666611116666"); break; case RUNE_NHI: _symb = SYMBOL_NHI, iPosX = 4, iPosY = 2, strcpy(sequence, "4444"); break; case RUNE_RHAA: _symb = SYMBOL_RHAA, iPosX = 2, iPosY = 0, strcpy(sequence, "22222"); break; case RUNE_SPACIUM: _symb = SYMBOL_SPACIUM, iPosX = 4, iPosY = 0, strcpy(sequence, "44444222266688"); break; case RUNE_STREGUM: _symb = SYMBOL_STREGUM, iPosX = 0, iPosY = 4, strcpy(sequence, "8888833338888"); break; case RUNE_TAAR: _symb = SYMBOL_TAAR, iPosX = 0, iPosY = 1, strcpy(sequence, "666222666"); break; case RUNE_TEMPUS: _symb = SYMBOL_TEMPUS, iPosX = 0, iPosY = 4, strcpy(sequence, "88886662226668866"); break; case RUNE_TERA: _symb = SYMBOL_TERA, iPosX = 0, iPosY = 3, strcpy(sequence, "99922266"); break; case RUNE_VISTA: _symb = SYMBOL_VISTA, iPosX = 1, iPosY = 0, strcpy(sequence, "333111"); break; case RUNE_VITAE: _symb = SYMBOL_VITAE, iPosX = 0, iPosY = 2, strcpy(sequence, "66666888"); break; case RUNE_YOK: _symb = SYMBOL_YOK, iPosX = 0, iPosY = 0, strcpy(sequence, "222226666888"); break; default: return; } void *ptr; ptr = realloc(io->symboldraw, sizeof(SYMBOL_DRAW)); if (!ptr) return; io->symboldraw = ptr; SYMBOL_DRAW *sd = (SYMBOL_DRAW *)io->symboldraw; sd->duration = duration < 1.0F ? 1 : (short)(long)duration; strcpy(sd->sequence, sequence); sd->starttime = ARXTimeUL(); sd->lasttim = 0; sd->symbol = (short)_symb; sd->lastpos.x = io->pos.x - EEsin(DEG2RAD(MAKEANGLE(io->angle.b - 45.0F + iPosX*2))) * 60.0F; sd->lastpos.y = io->pos.y - 120.0F - iPosY*5; sd->lastpos.z = io->pos.z + EEcos(DEG2RAD(MAKEANGLE(io->angle.b - 45.0F + iPosX*2))) * 60.0F; ARX_CHECK_CHAR(iPosX); ARX_CHECK_CHAR(iPosY); sd->cPosStartX = ARX_CLEAN_WARN_CAST_CHAR(iPosX); sd->cPosStartY = ARX_CLEAN_WARN_CAST_CHAR(iPosY); io->GameFlags &= ~GFLAG_INVISIBILITY; } //----------------------------------------------------------------------------- void ARX_SPELLS_RequestSymbolDraw3(const char *_pcName,char *_pcRes) { if (!strcmp(_pcName, "AAM")) strcpy(_pcRes, "6666"); else if (!strcmp(_pcName, "CETRIUS")) strcpy(_pcRes, "33388886666"); else if (!strcmp(_pcName, "COMUNICATUM")) strcpy(_pcRes, "6666622244442226666"); else if (!strcmp(_pcName, "COSUM")) strcpy(_pcRes, "66666222244448888"); else if (!strcmp(_pcName, "FOLGORA")) strcpy(_pcRes, "99993333"); else if (!strcmp(_pcName, "FRIDD")) strcpy(_pcRes, "888886662222"); else if (!strcmp(_pcName, "KAOM")) strcpy(_pcRes, "44122366"); else if (!strcmp(_pcName, "MEGA")) strcpy(_pcRes, "88888"); else if (!strcmp(_pcName, "MORTE")) strcpy(_pcRes, "66666222"); else if (!strcmp(_pcName, "MOVIS")) strcpy(_pcRes, "666611116666"); else if (!strcmp(_pcName, "NHI")) strcpy(_pcRes, "4444"); else if (!strcmp(_pcName, "RHAA")) strcpy(_pcRes, "22222"); else if (!strcmp(_pcName, "SPACIUM")) strcpy(_pcRes, "44444222266688"); else if (!strcmp(_pcName, "STREGUM")) strcpy(_pcRes, "8888833338888"); else if (!strcmp(_pcName, "TAAR")) strcpy(_pcRes, "666222666"); else if (!strcmp(_pcName, "TEMPUS")) strcpy(_pcRes, "88886662226668866"); else if (!strcmp(_pcName, "TERA")) strcpy(_pcRes, "99922266"); else if (!strcmp(_pcName, "VISTA")) strcpy(_pcRes, "333111"); else if (!strcmp(_pcName, "VITAE")) strcpy(_pcRes, "66666888"); else if (!strcmp(_pcName, "YOK")) strcpy(_pcRes, "222226666888"); else if (!strcmp(_pcName, "AKBAA")) strcpy(_pcRes, "22666772222"); } #define OFFSET_X 8*2//0 #define OFFSET_Y 6*2//0 //----------------------------------------------------------------------------- void GetSymbVector(char c,EERIE_S2D * vec) { switch (c) { case '1' : vec->x = -OFFSET_X, vec->y = OFFSET_Y; break; case '2' : vec->x = 0, vec->y = OFFSET_Y; break; case '3' : vec->x = OFFSET_X, vec->y = OFFSET_Y; break; case '4' : vec->x = -OFFSET_X, vec->y = 0; break; case '6' : vec->x = OFFSET_X, vec->y = 0; break; case '7' : vec->x = -OFFSET_X, vec->y = -OFFSET_Y; break; case '8' : vec->x = 0, vec->y = -OFFSET_Y; break; case '9' : vec->x = OFFSET_X, vec->y = -OFFSET_Y; break; default : vec->x = 0, vec->y = 0; break; } } //----------------------------------------------------------------------------- BOOL MakeSpellName(char * spell, const long &num) { switch (num) { // Level 1 case SPELL_MAGIC_SIGHT : strcpy(spell, "MAGIC_SIGHT"); break; case SPELL_MAGIC_MISSILE : strcpy(spell, "MAGIC_MISSILE"); break; case SPELL_IGNIT : strcpy(spell, "IGNIT"); break; case SPELL_DOUSE : strcpy(spell, "DOUSE"); break; case SPELL_ACTIVATE_PORTAL : strcpy(spell, "ACTIVATE_PORTAL"); break; // Level 2 case SPELL_HEAL : strcpy(spell, "HEAL"); break; case SPELL_DETECT_TRAP : strcpy(spell, "DETECT_TRAP"); break; case SPELL_ARMOR : strcpy(spell, "ARMOR"); break; case SPELL_LOWER_ARMOR : strcpy(spell, "LOWER_ARMOR"); break; case SPELL_HARM : strcpy(spell, "HARM"); break; // Level 3 case SPELL_SPEED : strcpy(spell, "SPEED"); break; case SPELL_DISPELL_ILLUSION : strcpy(spell, "DISPELL_ILLUSION"); break; case SPELL_FIREBALL : strcpy(spell, "FIREBALL"); break; case SPELL_CREATE_FOOD : strcpy(spell, "CREATE_FOOD"); break; case SPELL_ICE_PROJECTILE : strcpy(spell, "ICE_PROJECTILE"); break; // Level 4 case SPELL_BLESS : strcpy(spell, "BLESS"); break; case SPELL_DISPELL_FIELD : strcpy(spell, "DISPELL_FIELD"); break; case SPELL_FIRE_PROTECTION : strcpy(spell, "FIRE_PROTECTION"); break; case SPELL_TELEKINESIS : strcpy(spell, "TELEKINESIS"); break; case SPELL_CURSE : strcpy(spell, "CURSE"); break; case SPELL_COLD_PROTECTION : strcpy(spell, "COLD_PROTECTION"); break; // Level 5 case SPELL_RUNE_OF_GUARDING : strcpy(spell, "RUNE_OF_GUARDING"); break; case SPELL_LEVITATE : strcpy(spell, "LEVITATE"); break; case SPELL_CURE_POISON : strcpy(spell, "CURE_POISON"); break; case SPELL_REPEL_UNDEAD : strcpy(spell, "REPEL_UNDEAD"); break; case SPELL_POISON_PROJECTILE : strcpy(spell, "POISON_PROJECTILE"); break; // Level 6 case SPELL_RISE_DEAD : strcpy(spell, "RAISE_DEAD"); break; case SPELL_PARALYSE : strcpy(spell, "PARALYSE"); break; case SPELL_CREATE_FIELD : strcpy(spell, "CREATE_FIELD"); break; case SPELL_DISARM_TRAP : strcpy(spell, "DISARM_TRAP"); break; case SPELL_SLOW_DOWN : strcpy(spell, "SLOWDOWN"); break; // Level 7 case SPELL_FLYING_EYE : strcpy(spell, "FLYING_EYE"); break; case SPELL_FIRE_FIELD : strcpy(spell, "FIRE_FIELD"); break; case SPELL_ICE_FIELD : strcpy(spell, "ICE_FIELD"); break; case SPELL_LIGHTNING_STRIKE : strcpy(spell, "LIGHTNING_STRIKE"); break; case SPELL_CONFUSE : strcpy(spell, "CONFUSE"); break; // Level 8 case SPELL_INVISIBILITY : strcpy(spell, "INVISIBILITY"); break; case SPELL_MANA_DRAIN : strcpy(spell, "MANA_DRAIN"); break; case SPELL_EXPLOSION : strcpy(spell, "EXPLOSION"); break; case SPELL_ENCHANT_WEAPON : strcpy(spell, "ENCHANT_WEAPON"); break; case SPELL_LIFE_DRAIN : strcpy(spell, "LIFE_DRAIN"); break; // Level 9 case SPELL_SUMMON_CREATURE : strcpy(spell, "SUMMON_CREATURE"); break; case SPELL_FAKE_SUMMON : strcpy(spell, "FAKE_SUMMON"); break; case SPELL_NEGATE_MAGIC : strcpy(spell, "NEGATE_MAGIC"); break; case SPELL_INCINERATE : strcpy(spell, "INCINERATE"); break; case SPELL_MASS_PARALYSE : strcpy(spell, "MASS_PARALYSE"); break; // Level 10 case SPELL_MASS_LIGHTNING_STRIKE : strcpy(spell, "MASS_LIGHTNING_STRIKE"); break; case SPELL_CONTROL_TARGET : strcpy(spell, "CONTROL"); break; case SPELL_FREEZE_TIME : strcpy(spell, "FREEZE_TIME"); break; case SPELL_MASS_INCINERATE : strcpy(spell, "MASS_INCINERATE"); break; default : return FALSE; } return TRUE; } //----------------------------------------------------------------------------- long GetSpellId(const char *spell) { if (!stricmp(spell, "ACTIVATE_PORTAL")) return SPELL_ACTIVATE_PORTAL; if (!stricmp(spell, "DOUSE")) return SPELL_DOUSE; if (!stricmp(spell, "IGNIT")) return SPELL_IGNIT; if (!stricmp(spell, "MAGIC_SIGHT")) return SPELL_MAGIC_SIGHT; if (!stricmp(spell, "MAGIC_MISSILE")) return SPELL_MAGIC_MISSILE; // Level 2 if (!stricmp(spell, "ARMOR")) return SPELL_ARMOR; if (!stricmp(spell, "DETECT_TRAP")) return SPELL_DETECT_TRAP; if (!stricmp(spell, "HARM")) return SPELL_HARM; if (!stricmp(spell, "HEAL")) return SPELL_HEAL; if (!stricmp(spell, "LOWER_ARMOR")) return SPELL_LOWER_ARMOR; // Level 3 if (!stricmp(spell, "CREATE_FOOD")) return SPELL_CREATE_FOOD; if (!stricmp(spell, "DISPELL_ILLUSION")) return SPELL_DISPELL_ILLUSION; if (!stricmp(spell, "FIREBALL")) return SPELL_FIREBALL; if (!stricmp(spell, "ICE_PROJECTILE")) return SPELL_ICE_PROJECTILE; if (!stricmp(spell, "SPEED")) return SPELL_SPEED; // Level 4 if (!stricmp(spell, "BLESS")) return SPELL_BLESS; if (!stricmp(spell, "COLD_PROTECTION")) return SPELL_COLD_PROTECTION; if (!stricmp(spell, "CURSE")) return SPELL_CURSE; if (!stricmp(spell, "DISPELL_FIELD")) return SPELL_DISPELL_FIELD; if (!stricmp(spell, "FIRE_PROTECTION")) return SPELL_FIRE_PROTECTION; if (!stricmp(spell, "TELEKINESIS")) return SPELL_TELEKINESIS; // Level 5 if (!stricmp(spell, "CURE_POISON")) return SPELL_CURE_POISON; if (!stricmp(spell, "LEVITATE")) return SPELL_LEVITATE; if (!stricmp(spell, "POISON_PROJECTILE")) return SPELL_POISON_PROJECTILE; if (!stricmp(spell, "REPEL_UNDEAD")) return SPELL_REPEL_UNDEAD; if (!stricmp(spell, "RUNE_OF_GUARDING")) return SPELL_RUNE_OF_GUARDING; // Level 6 if (!stricmp(spell, "CREATE_FIELD")) return SPELL_CREATE_FIELD; if (!stricmp(spell, "DISARM_TRAP")) return SPELL_DISARM_TRAP; if (!stricmp(spell, "PARALYSE")) return SPELL_PARALYSE; if (!stricmp(spell, "RAISE_DEAD")) return SPELL_RISE_DEAD; if (!stricmp(spell, "SLOWDOWN")) return SPELL_SLOW_DOWN; // Level 7 if (!stricmp(spell, "CONFUSE")) return SPELL_CONFUSE; if (!stricmp(spell, "FIRE_FIELD")) return SPELL_FIRE_FIELD; if (!stricmp(spell, "FLYING_EYE")) return SPELL_FLYING_EYE; if (!stricmp(spell, "ICE_FIELD")) return SPELL_ICE_FIELD; if (!stricmp(spell, "LIGHTNING_STRIKE")) return SPELL_LIGHTNING_STRIKE; // Level 8 if (!stricmp(spell, "ENCHANT_WEAPON")) return SPELL_ENCHANT_WEAPON; if (!stricmp(spell, "EXPLOSION")) return SPELL_EXPLOSION; if (!stricmp(spell, "INVISIBILITY")) return SPELL_INVISIBILITY; if (!stricmp(spell, "LIFE_DRAIN")) return SPELL_LIFE_DRAIN; if (!stricmp(spell, "MANA_DRAIN")) return SPELL_MANA_DRAIN; // Level 9 if (!stricmp(spell, "INCINERATE")) return SPELL_INCINERATE; if (!stricmp(spell, "MASS_PARALYSE")) return SPELL_MASS_PARALYSE; if (!stricmp(spell, "NEGATE_MAGIC")) return SPELL_NEGATE_MAGIC; if (!stricmp(spell, "SUMMON_CREATURE")) return SPELL_SUMMON_CREATURE; if (!stricmp(spell, "FAKE_SUMMON")) return SPELL_FAKE_SUMMON; // Level 10 if (!stricmp(spell, "CONTROL")) return SPELL_CONTROL_TARGET; if (!stricmp(spell, "FREEZE_TIME")) return SPELL_FREEZE_TIME; if (!stricmp(spell, "MASS_INCINERATE")) return SPELL_MASS_INCINERATE; if (!stricmp(spell, "MASS_LIGHTNING_STRIKE")) return SPELL_MASS_LIGHTNING_STRIKE; return -1; } //----------------------------------------------------------------------------- void SPELLCAST_Notify(long num) { if (num < 0) return; if (num >= MAX_SPELLS) return; char spell[128]; long source = spells[num].caster; if (MakeSpellName(spell,spells[num].type)) { for (long i=0;i= 0) EVENT_SENDER = inter.iobj[source]; else EVENT_SENDER = NULL; char param[256]; sprintf(param,"%s %d",spell,(long)spells[num].caster_level); SendIOScriptEvent(inter.iobj[i], SM_SPELLCAST, param); } } } } //----------------------------------------------------------------------------- void SPELLCAST_NotifyOnlyTarget(long num) { if (num < 0) return; if (num >= MAX_SPELLS) return; if(spells[num].target<0) return; char spell[128]; long source = spells[num].caster; if (MakeSpellName(spell,spells[num].type)) { if (source >= 0) EVENT_SENDER = inter.iobj[source]; else EVENT_SENDER = NULL; char param[256]; sprintf(param,"%s %d",spell,(long)spells[num].caster_level); SendIOScriptEvent(inter.iobj[spells[num].target], SM_SPELLCAST, param); } } //----------------------------------------------------------------------------- void SPELLEND_Notify(long num) { if ( (num<0) || (num>=MAX_SPELLS) ) return; char spell[128]; long source=spells[num].caster; if (spells[num].type==SPELL_CONFUSE) { if (ValidIONum(source)) EVENT_SENDER = inter.iobj[source]; else EVENT_SENDER = NULL; if (ValidIONum(spells[num].target)) { if (MakeSpellName(spell,spells[num].type)) { char param[128]; INTERACTIVE_OBJ * targ= inter.iobj[spells[num].target]; sprintf(param,"%s %d",spell,(long)spells[num].caster_level); SendIOScriptEvent(targ,SM_SPELLEND,param); } } return; } // we only notify player spells end. if (MakeSpellName(spell,spells[num].type)) for (long i=0;ispellcast_data.castingspell>0) { if (io->symboldraw==NULL) { long tst=0; if (!(io->spellcast_data.spell_flags & SPELLCAST_FLAG_NOANIM) && (io->ioflags & IO_NPC)) { ANIM_USE * ause1=&io->animlayer[1]; if (ause1->cur_anim==io->anims[ANIM_CAST_START] && (ause1->flags & EA_ANIMEND)) { FinishAnim(io,ause1->cur_anim); ANIM_Set(ause1,io->anims[ANIM_CAST_CYCLE]); tst=1; } else if (ause1->cur_anim==io->anims[ANIM_CAST_CYCLE]) tst=1; else if (ause1->cur_anim!=io->anims[ANIM_CAST_START]) io->spellcast_data.castingspell=-1; } else tst=1; if ((io->spellcast_data.symb[0]!=255) && tst ) { long symb=io->spellcast_data.symb[0]; for (long j=0;j<3;j++) io->spellcast_data.symb[j]=io->spellcast_data.symb[j+1]; io->spellcast_data.symb[3]=255; ARX_SPELLS_RequestSymbolDraw2(io, symb, (1000-(io->spellcast_data.spell_level*60))*__max(io->speed_modif+io->basespeed,0.01f)); io->GameFlags &=~GFLAG_INVISIBILITY; } else if (tst)// cast spell !!! { io->GameFlags &=~GFLAG_INVISIBILITY; ARX_SPELLS_Launch(io->spellcast_data.castingspell,i,io->spellcast_data.spell_flags,io->spellcast_data.spell_level,io->spellcast_data.target,io->spellcast_data.duration); if (!(io->spellcast_data.spell_flags & SPELLCAST_FLAG_NOANIM) && (io->ioflags & IO_NPC)) { ANIM_USE * ause1=&io->animlayer[1]; AcquireLastAnim(io); FinishAnim(io,ause1->cur_anim); ANIM_Set(ause1,io->anims[ANIM_CAST]); } io->spellcast_data.castingspell=-1; } } } float rr=rnd(); if (io->flarecount) { if (io->dynlight==-1) io->dynlight=(short)GetFreeDynLight(); if (io->dynlight!=-1) { DynLight[io->dynlight].pos.x=io->pos.x-EEsin(DEG2RAD(MAKEANGLE(io->angle.b-45.f)))*60.f; DynLight[io->dynlight].pos.y=io->pos.y-120.f; DynLight[io->dynlight].pos.z=io->pos.z+EEcos(DEG2RAD(MAKEANGLE(io->angle.b-45.f)))*60.f; DynLight[io->dynlight].fallstart=140.f+(float)io->flarecount*0.333333f+rr*5.f; DynLight[io->dynlight].fallend=220.f+(float)io->flarecount*0.5f+rr*5.f; DynLight[io->dynlight].intensity=1.6f; DynLight[io->dynlight].exist=1; DynLight[io->dynlight].rgb.r=0.01f*io->flarecount*2; DynLight[io->dynlight].rgb.g=0.009f*io->flarecount*2; DynLight[io->dynlight].rgb.b=0.008f*io->flarecount*2; } } else if (io->dynlight>-1) { DynLight[io->dynlight].exist=0; io->dynlight=-1; } if (io->symboldraw) { SYMBOL_DRAW * sd=(SYMBOL_DRAW *)inter.iobj[i]->symboldraw; long tim=curtime-sd->starttime; if (tim>sd->duration) { if (io->dynlight!=-1) { DynLight[io->dynlight].time_creation = ARXTimeUL(); DynLight[io->dynlight].duration = 600; io->dynlight=-1; } free(io->symboldraw); io->symboldraw=NULL; continue; } long nbcomponents=strlen(sd->sequence); if (nbcomponents<=0) { free(io->symboldraw); io->symboldraw=NULL; continue; } float ti=((float)sd->duration/(float)nbcomponents); if (ti<=0) ti=1; EERIE_S2D pos1, vect, old_pos; long newtime=tim; long oldtime=sd->lasttim; if (oldtime>sd->duration) oldtime=sd->duration; if (newtime>sd->duration) newtime=sd->duration; sd->lasttim=(short)tim; pos1.x = (short)subj.centerx -OFFSET_X*2 + sd->cPosStartX*OFFSET_X; pos1.y = (short)subj.centery -OFFSET_Y*2 + sd->cPosStartY*OFFSET_Y; float div_ti=1.f/ti; if (io != inter.iobj[0]) { old_pos.x=pos1.x; old_pos.y=pos1.y; for (long j=0;jsequence[j],&vect); vect.x += vect.x >> 1; vect.y += vect.y >> 1; if (oldtime<=ti) { float ratio=(float)(oldtime)*div_ti; old_pos.x+=(short)(float)(ratio*(float)vect.x); old_pos.y+=(short)(float)(ratio*(float)vect.y); break; } old_pos.x+=vect.x; old_pos.y+=vect.y; oldtime-=(long)ti; } for (int j=0;jsequence[j],&vect); vect.x += vect.x >> 1; vect.y += vect.y >> 1; if (newtime<=ti) { float ratio=(float)(newtime)*div_ti; pos1.x+=(short)(float)(ratio*(float)vect.x); pos1.y+=(short)(float)(ratio*(float)vect.y); AddFlare(&pos1,0.1f,1,inter.iobj[i]); FlareLine(&old_pos,&pos1,inter.iobj[i]); break; } pos1.x+=vect.x; pos1.y+=vect.y; newtime-=(long)ti; } } else { int iMinX,iMinY,iMaxX,iMaxY; int iSizeX,iSizeY; ReCenterSequence(sd->sequence,iMinX,iMinY,iMaxX,iMaxY); iSizeX=iMaxX-iMinX; iSizeY=iMaxY-iMinY; pos1.x = 97; pos1.y = 64; long lPosX = (((513>>1)-lMaxSymbolDrawSizeX)>>1); long lPosY = (313-(((313*3/4)-lMaxSymbolDrawSizeY)>>1)); ARX_CHECK_SHORT(pos1.x + lPosX); ARX_CHECK_SHORT(pos1.y + lPosY); pos1.x += ARX_CLEAN_WARN_CAST_SHORT(lPosX); pos1.y += ARX_CLEAN_WARN_CAST_SHORT(lPosY); lPosX = ((lMaxSymbolDrawSizeX-iSizeX)>>1); lPosY = ((lMaxSymbolDrawSizeY-iSizeY)>>1); ARX_CHECK_SHORT(pos1.x + lPosX); ARX_CHECK_SHORT(pos1.y + lPosY); pos1.x += ARX_CLEAN_WARN_CAST_SHORT(lPosX); pos1.y += ARX_CLEAN_WARN_CAST_SHORT(lPosY); int iX = pos1.x-iMinX; int iY = pos1.y-iMinY; ARX_CHECK_SHORT(iX); ARX_CHECK_SHORT(iY); pos1.x = ARX_CLEAN_WARN_CAST_SHORT(iX); pos1.y = ARX_CLEAN_WARN_CAST_SHORT(iY); for (long j=0;jsequence[j],&vect); if (newtimesymboldraw) free(inter.iobj[i]->symboldraw), inter.iobj[i]->symboldraw = NULL; } //************************************************************************************* // //************************************************************************************* void ARX_SPELLS_AnalyseSYMBOL() { long csymb = -1; long sm = atoi(SpellMoves); switch (sm) { // COSUM case 62148 : case 632148 : case 62498 : case 62748 : case 6248 : csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_COSUM; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_COSUM); break; // COMUNICATUM case 632426 : case 627426 : case 634236 : case 624326 : case 62426 : csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_COMUNICATUM; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_COMUNICATUM); break; // FOLGORA case 9823 : case 9232 : case 983 : case 963 : case 923 : case 932 : case 93 : csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_FOLGORA; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_FOLGORA); break; // SPACIUM case 42368 : case 42678 : case 42698 : case 4268 : csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_SPACIUM; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_SPACIUM); break; // TERA case 9826 : case 92126 : case 9264 : case 9296 : case 926 : csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_TERA; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_TERA); break; // CETRIUS case 286 : case 3286 : case 23836 : case 38636 : case 2986 : case 2386 : case 386 : csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_CETRIUS; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_CETRIUS); break; // RHAA case 28 : case 2 : csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_RHAA; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_RHAA); break; // FRIDD case 98362 : case 8362 : case 8632 : case 8962 : case 862 : csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_FRIDD; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_FRIDD); break; // KAOM case 41236 : case 23 : case 236 : case 2369 : case 136 : case 12369 : case 1236 : if ((cur_arm>=0) && (cur_arm & 1) ) { cur_arm++; if (cur_arm>20) ApplySPArm(); } else cur_arm=-1; csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_KAOM; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_KAOM); break; // STREGUM case 82328 : case 8328 : case 2328 : case 8938 : case 8238 : case 838 : csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_STREGUM; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_STREGUM); break; // MORTE case 628 : case 621 : case 62 : csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_MORTE; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_MORTE); break; // TEMPUS case 962686 : case 862686 : case 8626862 : csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_TEMPUS; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_TEMPUS); break; // MOVIS case 6316: case 61236: case 6146: case 61216: case 6216: case 6416: case 62126: case 61264: case 6126: case 6136: case 616: csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_MOVIS; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_MOVIS); break; // NHI case 46: case 4: csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_NHI; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_NHI); break; // AAM case 64: case 6: csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_AAM; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_AAM); break; // YOK case 412369: case 2687: case 2698: case 2638: case 26386: case 2368: case 2689: case 268: csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_YOK; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_YOK); break; // TAAR case 6236: case 6264: case 626: csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_TAAR; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_TAAR); break; // MEGA case 82: case 8: if ((cur_arm>=0) && !(cur_arm & 1) ) { cur_arm++; } else cur_arm=-1; csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_MEGA; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_MEGA); break; // VISTA case 3614: case 361: case 341: case 3212: case 3214: case 312: case 314: case 321: case 31: csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_VISTA; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_VISTA); break; // VITAE case 698: case 68: csymb=SpellSymbol[CurrSpellSymbol++]=SYMBOL_VITAE; if (CurrSpellSymbol>=MAX_SPELL_SYMBOLS) CurrSpellSymbol=MAX_SPELL_SYMBOLS-1; ARX_SOUND_PlaySFX(SND_SYMB_VITAE); break; //-------------------------------------------------------------------------------------------------------------------- // Special UW mode case 238: case 2398: case 23898: case 236987: case 23698: if (uw_mode_pos == 0) uw_mode_pos++; goto failed; break; case 2382398: case 2829: case 23982398: case 39892398: case 2398938: case 28239898: case 238982398: case 238923898: case 28982398: case 3923989: case 292398: case 398329: case 38923898: case 2398289: case 289823898: case 2989238: case 29829: case 2389823898: case 2393239: case 38239: case 2982323989: case 3298232329: case 239829: case 2898239: case 28982898: case 389389: case 3892389: case 289289: case 289239: case 239289: case 2989298: case 2392398: case 238929: case 28923898: case 2929: case 2398298: case 239823898: case 28238: case 2892398: case 28298: case 298289: case 38929: case 2389238989: case 289298989: case 23892398: case 238239: case 29298: case 2329298: case 232389829: case 2389829: case 239239: case 282398: case 2398982398: case 2389239: case 2929898: case 3292398: case 23923298: case 23898239: case 3232929: case 2982398: case 238298: case 3939: if (uw_mode_pos == 1) { ApplySPuw(); } goto failed; break; case 161: case 1621: case 1261: if (cur_sm==0) cur_sm++; if (cur_bh==0) cur_bh++; if (cur_bh==2) cur_bh++; if (cur_sos==0) cur_sos++; if (cur_sos == 2) { cur_sos = 0; ApplyCurSOS(); } goto failed; break; case 83614: case 8361: case 8341: case 83212: case 83214: case 8312: case 8314: case 8321: case 831: case 82341: case 834: case 823: case 8234: case 8231: if (cur_pom==0) cur_pom++; if (cur_pnux==0) cur_pnux++; if (cur_pnux==2) cur_pnux++; if (cur_bh == 1) { cur_bh++; } if (cur_bh == 3) { cur_bh = 0; EERIE_OBJECT_SetBHMode(); } goto failed; break; break; case 83692: case 823982: case 83982: case 82369892: case 82392: case 83892: case 823282: case 8392: { if (cur_sm == 2) { cur_sm++; ApplySPBow(); } if (cur_mx == 0) { cur_mx = 1; } if (cur_mr == 0) { cur_mr = 1; } if (cur_pom == 2) { cur_pom++; ApplySPWep(); } goto failed; } break; case 98324: case 92324: case 89324: case 9324: case 9892324: case 9234: case 934: { if (cur_mr == 1) { cur_mr = 2; MakeCoolFx(&player.pos); } if (cur_mx == 1) { cur_mx = 2; MakeCoolFx(&player.pos); } if (cur_rf == 1) { cur_rf = 2; MakeCoolFx(&player.pos); } if (cur_sm==1) cur_sm++; goto failed; } break; case 3249: case 2349: case 323489: case 23249: case 3489: case 32498: case 349: { if (cur_mx == 2) { cur_mx = 3; ApplySPMax(); } goto failed; } break; case 26: { if (cur_pnux == 1) { cur_pnux++; } if (cur_pnux == 3) { cur_pnux++; ApplyCurPNux(); } goto failed; } break; case 9232187: case 93187: case 9234187: case 831878: case 923187: case 932187: case 93217: case 9317: { if (cur_pom==1) cur_pom++; if (cur_sos==1) cur_sos++; goto failed; } break; case 82313: case 8343: case 82343: case 83413: case 8313: { if (cur_mr == 2) { cur_mr = 3; MakeCoolFx(&player.pos); ApplyCurMr(); } if (cur_rf == 0) { cur_rf = 1; } goto failed; break; } case 86: if (cur_rf == 2) { cur_rf = 3; MakeCoolFx(&player.pos); ApplySPRf(); } goto failed; break; case 626262: { passwall++; if (passwall==3) { passwall=0; ApplyPasswall(); } } break; case 828282: { player.skin++; if ((player.skin==4) && (rnd()<0.9f)) player.skin++; if (player.skin>5) player.skin=0; ARX_EQUIPMENT_RecreatePlayerMesh(); goto failed; } break; default: { failed: ; _TCHAR tex[512]; if (strlen(SpellMoves)>=127) SpellMoves[127]=0; strcpy(LAST_FAILED_SEQUENCE,SpellMoves); if (!NO_TEXT_AT_ALL) { _stprintf(tex, _T("Unknown Symbol - %S"), SpellMoves); ARX_SPEECH_Add(NULL, tex); } } } bPrecastSpell = false; // wanna precast? if (ARX_IMPULSE_Pressed(CONTROLS_CUST_STEALTHMODE)) { bPrecastSpell = true; } } //************************************************************************************* // //************************************************************************************* BOOL ARX_SPELLS_AnalyseSPELL() { long caster = 0; // Local Player long PRE_CAST=0; if ( ARX_IMPULSE_Pressed(CONTROLS_CUST_STEALTHMODE) || bPrecastSpell) PRE_CAST = SPELLCAST_FLAG_PRECAST; bPrecastSpell = false; if ( (SpellSymbol[0]==SYMBOL_MEGA) && (SpellSymbol[1]==SYMBOL_MEGA) && (SpellSymbol[2]==SYMBOL_MEGA) && (SpellSymbol[3]==SYMBOL_AAM) && (SpellSymbol[4]==SYMBOL_VITAE) && (SpellSymbol[5]==SYMBOL_TERA) ) { cur_mega=10; return ARX_SPELLS_Launch(SPELL_SUMMON_CREATURE,caster,PRE_CAST); } switch (SpellSymbol[0]) { case SYMBOL_RHAA : switch (SpellSymbol[1]) { case SYMBOL_STREGUM : switch (SpellSymbol[2]) { case SYMBOL_VITAE :// CURSE Level 4 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_CURSE,caster,PRE_CAST); break; } break; case SYMBOL_TEMPUS: // FREEZE TIME Level 10 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_FREEZE_TIME,caster,PRE_CAST); break; case SYMBOL_KAOM : // LOWER ARMOR Level 2 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_LOWER_ARMOR,caster,PRE_CAST); break; case SYMBOL_MOVIS : // SLOW DOWN Level 6 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_SLOW_DOWN,caster,PRE_CAST); break; case SYMBOL_VITAE : // HARM Level 2 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_HARM,caster,PRE_CAST); break; case SYMBOL_VISTA: // CONFUSE Level 7 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_CONFUSE,caster,PRE_CAST); break; } break; case SYMBOL_MEGA : switch (SpellSymbol[1]) { case SYMBOL_NHI: switch (SpellSymbol[2]) { case SYMBOL_MOVIS: // MASS PARALYSIS Level 9 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_MASS_PARALYSE,caster,PRE_CAST); break; } break; case SYMBOL_KAOM: //ARMOR Level 2 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_ARMOR,caster,PRE_CAST); break; case SYMBOL_VISTA: // MAGIC SIGHT Level 1 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_MAGIC_SIGHT,caster,PRE_CAST); break; case SYMBOL_VITAE: // HEAL Level 2 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_HEAL,caster,PRE_CAST); break; case SYMBOL_MOVIS: // SPEED Level 3 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_SPEED,caster,PRE_CAST); break; case SYMBOL_STREGUM: switch (SpellSymbol[2]) { case SYMBOL_VITAE:// SANCTIFY OBJECT Level 4 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_BLESS,caster,PRE_CAST); break; case SYMBOL_COSUM: // ENCHANT WEAPON Level 8 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_ENCHANT_WEAPON,caster,PRE_CAST); break; } break; case SYMBOL_AAM: switch (SpellSymbol[2]) { case SYMBOL_MEGA: switch (SpellSymbol[3]) { case SYMBOL_YOK: // MASS INCINERATE Level 10 if (SpellSymbol[4]==255) return ARX_SPELLS_Launch(SPELL_MASS_INCINERATE,caster,PRE_CAST); break; } break; } break; case SYMBOL_SPACIUM: switch (SpellSymbol[2]) { case SYMBOL_NONE : if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_ACTIVATE_PORTAL,caster,PRE_CAST); break; case SYMBOL_MOVIS : // LEVITATE Level 5 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_LEVITATE,caster,PRE_CAST); break; } break; } break; case SYMBOL_NHI: switch (SpellSymbol[1]) { case SYMBOL_MOVIS: // PARALYSE Level 6 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_PARALYSE,caster,PRE_CAST); break; case SYMBOL_CETRIUS: // Cure POISON Level 5 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_CURE_POISON,caster,PRE_CAST); break; case SYMBOL_YOK: // DOUSE Level 1 Spell if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_DOUSE,caster,PRE_CAST); break; case SYMBOL_STREGUM: switch (SpellSymbol[2]) { case SYMBOL_VISTA: // DISPELL ILLUSION Level 3 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_DISPELL_ILLUSION,caster,PRE_CAST); break; case SYMBOL_SPACIUM: // NEGATE MAGIC Level 9 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_NEGATE_MAGIC,caster,PRE_CAST); break; } break; case SYMBOL_SPACIUM: // DISPEL FIELD Level 4 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_DISPELL_FIELD,caster,PRE_CAST); break; case SYMBOL_MORTE: switch (SpellSymbol[2]) { case SYMBOL_COSUM: // DISARM TRAP Level 6 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_DISARM_TRAP,caster,PRE_CAST); break; } break; case SYMBOL_VISTA: switch (SpellSymbol[2]) { case SYMBOL_NONE : if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_INVISIBILITY,caster,PRE_CAST); break; } break; } break; case SYMBOL_VISTA: switch (SpellSymbol[1]) { case SYMBOL_MOVIS: // FLYING EYE Level 7 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_FLYING_EYE,caster,PRE_CAST); break; } break; case SYMBOL_MORTE: switch (SpellSymbol[1]) { case SYMBOL_KAOM: // REPEL UNDEAD Level 5 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_REPEL_UNDEAD,caster,PRE_CAST); break; case SYMBOL_COSUM: switch (SpellSymbol[2]) { case SYMBOL_VISTA: //DETECT_TRAP Level 2 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_DETECT_TRAP,caster,PRE_CAST); break; } break; } break; case SYMBOL_MOVIS: switch (SpellSymbol[1]) { case SYMBOL_COMUNICATUM: // CONTROL TARGET Level 10 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_CONTROL_TARGET,caster,PRE_CAST); break; } break; case SYMBOL_STREGUM: switch (SpellSymbol[1]) { case SYMBOL_MOVIS: // MANA_DRAIN Level 8 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_MANA_DRAIN,caster,PRE_CAST); break; } break; case SYMBOL_AAM: switch (SpellSymbol[1]) { case SYMBOL_MEGA : switch (SpellSymbol[2]) { case SYMBOL_YOK: // INCINERATE Level 9 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_INCINERATE,caster,PRE_CAST); break; case SYMBOL_MORTE: // EXPLOSION Level 8 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_EXPLOSION,caster,PRE_CAST); break; } break; case SYMBOL_KAOM: switch (SpellSymbol[2]) { case SYMBOL_SPACIUM: // CREATE FIELD Level 6 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_CREATE_FIELD,caster,PRE_CAST); break; } break; case SYMBOL_MORTE: switch (SpellSymbol[2]) { case SYMBOL_VITAE: // RISE DEAD Level 6 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_RISE_DEAD,caster,PRE_CAST); break; case SYMBOL_COSUM: // RUNE OF GUARDING Level 5 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_RUNE_OF_GUARDING,caster,PRE_CAST); break; } break; case SYMBOL_VITAE: switch (SpellSymbol[2]) { case SYMBOL_TERA: // SUMMON CREATURE Level 9 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_SUMMON_CREATURE,caster,PRE_CAST); break; case SYMBOL_COSUM: // CREATE_FOOD Level 3 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_CREATE_FOOD,caster,PRE_CAST); break; } break; case SYMBOL_FOLGORA: switch (SpellSymbol[2]) { case SYMBOL_TAAR: // LIGHTNING STRIKE Level 7 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_LIGHTNING_STRIKE,caster,PRE_CAST); break; case SYMBOL_SPACIUM: // MASS LIGHTNING Level 10 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_MASS_LIGHTNING_STRIKE,caster,PRE_CAST); break; } break; case SYMBOL_YOK: switch (SpellSymbol[2]) { case SYMBOL_NONE : // IGNIT Level 1 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_IGNIT,caster,PRE_CAST); break; case SYMBOL_SPACIUM: // FIRE FIELD Level 7 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_FIRE_FIELD,caster,PRE_CAST); break; case SYMBOL_TAAR: // FIREBALL Level 3 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_FIREBALL,caster,PRE_CAST); break; } break; case SYMBOL_FRIDD: switch (SpellSymbol[2]) { case SYMBOL_SPACIUM: // ICE FIELD Level 7 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_ICE_FIELD,caster,PRE_CAST); break; case SYMBOL_TAAR: // ICE PROJECTILE Level 3 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_ICE_PROJECTILE,caster,PRE_CAST); break; } break; case SYMBOL_CETRIUS: switch (SpellSymbol[2]) { case SYMBOL_TAAR: // POISON PROJECTILE Level 5 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_POISON_PROJECTILE,caster,PRE_CAST); break; } break; case SYMBOL_TAAR: switch (SpellSymbol[2]) { case SYMBOL_NONE :// MAGIC MISSILE Level 1 if (SpellSymbol[3]==255) return ARX_SPELLS_Launch(SPELL_MAGIC_MISSILE,caster,PRE_CAST); break; } break; } break; case SYMBOL_YOK: switch (SpellSymbol[1]) { case SYMBOL_KAOM: // FIRE PROTECTION Level 4 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_FIRE_PROTECTION,caster,PRE_CAST); break; } break; case SYMBOL_FRIDD: switch (SpellSymbol[1]) { case SYMBOL_KAOM: // ICE PROTECTION Level 4 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_COLD_PROTECTION,caster,PRE_CAST); break; } break; case SYMBOL_VITAE: switch (SpellSymbol[1]) { case SYMBOL_MOVIS: // LIFE_DRAIN Level 8 Spell if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_LIFE_DRAIN,caster,PRE_CAST); break; } break; case SYMBOL_SPACIUM: switch (SpellSymbol[1]) { case SYMBOL_COMUNICATUM: // TELEKINESIS Level 4 if (SpellSymbol[2]==255) return ARX_SPELLS_Launch(SPELL_TELEKINESIS,caster,PRE_CAST); break; } break; } ARX_SPELLS_Fizzle(-1); if (player.SpellToMemorize.bSpell) { CurrSpellSymbol=0; player.SpellToMemorize.bSpell = false; } return -1; } long No_MagicAllowed() { ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE); return -1; } extern long PLAYER_PARALYSED; //************************************************************************************* // //************************************************************************************* void ARX_SPELLS_ManageMagic() { if (ARXmenu.currentmode!=AMCM_OFF) return; INTERACTIVE_OBJ * io=inter.iobj[0]; if (!io) return; if ((io->animlayer[1].cur_anim == io->anims[ANIM_BARE_UNREADY]) || (io->animlayer[1].cur_anim == io->anims[ANIM_DAGGER_UNREADY_PART_1]) || (io->animlayer[1].cur_anim == io->anims[ANIM_1H_UNREADY_PART_1]) || (io->animlayer[1].cur_anim == io->anims[ANIM_2H_UNREADY_PART_1]) || (io->animlayer[1].cur_anim == io->anims[ANIM_MISSILE_UNREADY_PART_1]) || (io->animlayer[1].cur_anim == io->anims[ANIM_DAGGER_UNREADY_PART_2]) || (io->animlayer[1].cur_anim == io->anims[ANIM_1H_UNREADY_PART_2]) || (io->animlayer[1].cur_anim == io->anims[ANIM_2H_UNREADY_PART_2]) || (io->animlayer[1].cur_anim == io->anims[ANIM_MISSILE_UNREADY_PART_2])) return; snip++; if ((!(player.Current_Movement & PLAYER_CROUCH)) && (!BLOCK_PLAYER_CONTROLS && (ARX_IMPULSE_Pressed(CONTROLS_CUST_MAGICMODE))) && (!PLAYER_PARALYSED)) { if (player.Interface & INTER_COMBATMODE) { WILLRETURNTOCOMBATMODE=1; ARX_INTERFACE_Combat_Mode(0); bGToggleCombatModeWithKey=false; ResetAnim(&inter.iobj[0]->animlayer[1]); inter.iobj[0]->animlayer[1].flags&=~EA_LOOP; } if ((TRUE_PLAYER_MOUSELOOK_ON)) { WILLRETURNTOFREELOOK = 1; TRUE_PLAYER_MOUSELOOK_ON &= ~1; } if (player.doingmagic!=2) { player.doingmagic=2; if (inter.iobj[0]->anims[ANIM_CAST_START]) { AcquireLastAnim(inter.iobj[0]); ANIM_Set(&inter.iobj[0]->animlayer[1],inter.iobj[0]->anims[ANIM_CAST_START]); MAGICMODE = 1; } } if (snip >= 2) { if ((!EERIEMouseButton & 1) && (ARX_FLARES_broken==0)) { ARX_FLARES_broken=2; PIPOrgb++; if (PIPOrgb>2) PIPOrgb=0; } if (EERIEMouseButton & 1) { EERIE_S2D pos,pos2; pos.x = DANAEMouse.x; pos.y = DANAEMouse.y; extern long TRUE_PLAYER_MOUSELOOK_ON; if (TRUE_PLAYER_MOUSELOOK_ON) { pos.x = MemoMouse.x; pos.y = MemoMouse.y; } pos2.x=Lm.x; pos2.y=Lm.y; if (!ARX_FLARES_broken) FlareLine(&pos2,&pos); if (rnd()>0.6) AddFlare(&pos,1.f,-1); else AddFlare(&pos,1.f,3); OPIPOrgb=PIPOrgb; Lm.x = DANAEMouse.x; Lm.y = DANAEMouse.y; if (TRUE_PLAYER_MOUSELOOK_ON) { Lm.x = MemoMouse.x; Lm.y = MemoMouse.y; } ARX_FLARES_broken=0; if (!ARX_SOUND_IsPlaying(SND_MAGIC_DRAW)) ARX_SOUND_PlaySFX(SND_MAGIC_DRAW, NULL, 1.0F, ARX_SOUND_PLAY_LOOPED); } else { ARX_SOUND_Stop(SND_MAGIC_DRAW); } snip=0; } } else { ARX_FLARES_broken=1; PIPOrgb++; if (PIPOrgb>2) PIPOrgb=0; if (player.doingmagic!=0)//==2) { player.doingmagic=0;//1 if (inter.iobj[0]->anims[ANIM_CAST_END]) { AcquireLastAnim(inter.iobj[0]); ANIM_Set(&inter.iobj[0]->animlayer[1],inter.iobj[0]->anims[ANIM_CAST_END]); } ARX_FLARES_broken=3; } } if (ARX_FLARES_broken==3) { cur_arm=0; cur_mega=0; passwall=0; if (cur_mr!=3) cur_mr=0; if (cur_mx!=3) cur_mx=0; if (cur_rf!=3) cur_rf=0; if (cur_pom!=3) cur_pom=0; if (cur_pnux<3) cur_pnux=0; if (cur_sm<3) cur_sm=0; cur_bh=0; cur_sos=0; if (CurrSpellSymbol != 0) { if (ARX_SPELLS_AnalyseSPELL()!=-1) { if (inter.iobj[0]->anims[ANIM_CAST]) { AcquireLastAnim(inter.iobj[0]); ANIM_Set(&inter.iobj[0]->animlayer[1],inter.iobj[0]->anims[ANIM_CAST]); } } } ARX_FLARES_broken=1; if (WILLRETURNTOCOMBATMODE) { player.Interface|=INTER_COMBATMODE; player.Interface|=INTER_NO_STRIKE; ARX_EQUIPMENT_LaunchPlayerReadyWeapon(); player.doingmagic=0; WILLRETURNTOCOMBATMODE=0; if(INTERNATIONAL_MODE) { TRUE_PLAYER_MOUSELOOK_ON|=1; bRenderInCursorMode=false; } } if (WILLRETURNTOFREELOOK) { TRUE_PLAYER_MOUSELOOK_ON |= 1; WILLRETURNTOFREELOOK = 0; } ARX_SPELLS_ResetRecognition(); } else if (ARX_FLARES_broken==2) { ARX_SPELLS_Analyse(); if (SpellMoves[0] != 0) ARX_SPELLS_AnalyseSYMBOL(); ARX_FLARES_broken = 1; } } //----------------------------------------------------------------------------- long CanPayMana(long num,float cost, bool _bSound = true) { if (num<0) return 0; if (spells[num].flags & SPELLCAST_FLAG_NOMANA) return 1; if (spells[num].caster==0) { if (player.manaioflags & IO_NPC) { if (inter.iobj[spells[num].caster]->_npcdata->mana_npcdata->mana-=cost; return 1; } } return 0; } //----------------------------------------------------------------------------- // Resets Spell Recognition void ARX_SPELLS_ResetRecognition() { for (int i = 0; ix; plist[CurrPoint].y = pos->y; CurrPoint++; if (CurrPoint >= MAX_POINTS) CurrPoint = MAX_POINTS - 1; } //----------------------------------------------------------------------------- long TemporaryGetSpellTarget(const EERIE_3D *from) { float mindist(99999999.0F); long found(0); for (long i(1); i < inter.nbmax; i++) if (inter.iobj[i] && inter.iobj[i]->ioflags & IO_NPC) { float dist(EEDistance3D(from,&inter.iobj[i]->pos)); if (dist < mindist) { found = i; mindist = dist; } } return found; } //----------------------------------------------------------------------------- void ARX_SPELLS_Analyse() { long x = 0, xx = 0, y = 0, yy = 0, dx = 0, dy = 0; long i = 0; float pente = 0, a = 0, b = 0; unsigned char dirs[MAX_POINTS]; unsigned char lastdir = 255; long cdir = 0; long cx = 0, cy = 0; char chaine[4096]; for ( i = 0 ; i < CurrPoint ; i++ ) { x = plist[i].x; y = plist[i].y; if ( i > 0 ) { dx = ( xx + cx ) - x; dy = ( yy + cy ) - y; if ( Distance2D( (float)xx, (float)yy, (float)x, (float)y ) > 10 ) { xx = xx + cx; yy = yy + cy; a = (float)( abs( dx ) ); b = (float)( abs( dy ) ); if ( b != 0.f ) { pente = a / b; if ( ( pente > 0.4f ) && ( pente < 2.5f ) ) //une diagonale { if ( ( dx < 0 ) && ( dy < 0 ) ) //on a bougé vers droite/bas { if ( lastdir != ADOWNRIGHT ) { lastdir = dirs[cdir] = ADOWNRIGHT; cdir++; } } else if ( ( dx > 0 ) && ( dy < 0 ) ) //on a bougé vers gauche/bas { if ( lastdir != ADOWNLEFT ) { lastdir = dirs[cdir] = ADOWNLEFT; cdir++; } } else if ( ( dx < 0 ) && ( dy > 0 ) ) //on a bougé vers droite/haut { if ( lastdir != AUPRIGHT ) { lastdir = dirs[cdir] = AUPRIGHT; cdir++; } } else if ( ( dx > 0 ) && ( dy > 0 ) ) //on a bougé vers gauche/haut { if ( lastdir != AUPLEFT ) { lastdir = dirs[cdir] = AUPLEFT; cdir++; } } goto lasuite; } } if ( abs( dx ) > abs( dy ) ) //mouvement latéral plus important { if ( dx < 0 ) //on a bougé vers la droite { if ( lastdir != ARIGHT ) { lastdir = dirs[cdir] = ARIGHT; cdir++; } } else //on a bougé vers la gauche { if ( lastdir != ALEFT ) { lastdir = dirs[cdir] = ALEFT; cdir++; } } } else //mouvement vertical plus significatif { if ( dy < 0 ) //on a bougé vers le bas { if ( lastdir != ADOWN ) { lastdir = dirs[cdir] = ADOWN; cdir++; } } else //on a bougé vers le haut { if ( lastdir != AUP ) { lastdir = dirs[cdir] = AUP; cdir++; } } } } } lasuite: ; xx = x; yy = y; } strcpy( SpellMoves, "" ); if ( cdir > 0 ) { *chaine = 0; for ( i = 0 ; i < cdir ; i++ ) { switch ( dirs[i] ) { case AUP: strcat( chaine, "UP \n " ); spell[CurrSlot].SlotDir = 0; strcat( SpellMoves, "8" ); //uses PAD values break; case ADOWN: strcat( chaine, "DOWN \n " ); spell[CurrSlot].SlotDir = 4; strcat( SpellMoves, "2" ); break; case ALEFT: strcat( chaine, "LEFT \n " ); spell[CurrSlot].SlotDir = 6; strcat( SpellMoves, "4" ); break; case ARIGHT: strcat( chaine, "RIGHT \n " ); spell[CurrSlot].SlotDir = 2; strcat( SpellMoves, "6" ); break; case AUPRIGHT: strcat( chaine, "UP-RIGHT \n " ); spell[CurrSlot].SlotDir = 1; strcat( SpellMoves, "9" ); break; case ADOWNRIGHT: strcat( chaine, "DOWN-RIGHT \n " ); spell[CurrSlot].SlotDir = 3; strcat( SpellMoves, "3" ); break; case AUPLEFT: strcat( chaine, "UP-LEFT \n " ); spell[CurrSlot].SlotDir = 7; strcat( SpellMoves, "7" ); break; case ADOWNLEFT: strcat( chaine, "DOWN-LEFT \n " ); spell[CurrSlot].SlotDir = 5; strcat( SpellMoves, "1" ); break; } } } } //KNOWNSPELLS knownspells; //----------------------------------------------------------------------------- static void ARX_SPEELS_GetMaxRect(char *_pcName) { char tcTxt[32]; int iMinX,iMinY,iMaxX,iMaxY; int iSizeX,iSizeY; ARX_SPELLS_RequestSymbolDraw3(_pcName,tcTxt); ReCenterSequence(tcTxt,iMinX,iMinY,iMaxX,iMaxY); iSizeX=iMaxX-iMinX; iSizeY=iMaxY-iMinY; lMaxSymbolDrawSizeX=__max(iSizeX,lMaxSymbolDrawSizeX); lMaxSymbolDrawSizeY=__max(iSizeY,lMaxSymbolDrawSizeY); } //----------------------------------------------------------------------------- // Initializes Spell engine (Called once at DANAE startup) void ARX_SPELLS_Init(LPDIRECT3DDEVICE7 m_pd3dDevice) { lMaxSymbolDrawSizeX=INT_MIN; lMaxSymbolDrawSizeY=INT_MIN; ARX_SPEELS_GetMaxRect("AAM"); ARX_SPEELS_GetMaxRect("CETRIUS"); ARX_SPEELS_GetMaxRect("COMUNICATUM"); ARX_SPEELS_GetMaxRect("COSUM"); ARX_SPEELS_GetMaxRect("FOLGORA"); ARX_SPEELS_GetMaxRect("FRIDD"); ARX_SPEELS_GetMaxRect("KAOM"); ARX_SPEELS_GetMaxRect("MEGA"); ARX_SPEELS_GetMaxRect("MORTE"); ARX_SPEELS_GetMaxRect("MOVIS"); ARX_SPEELS_GetMaxRect("NHI"); ARX_SPEELS_GetMaxRect("RHAA"); ARX_SPEELS_GetMaxRect("SPACIUM"); ARX_SPEELS_GetMaxRect("STREGUM"); ARX_SPEELS_GetMaxRect("TAAR"); ARX_SPEELS_GetMaxRect("TEMPUS"); ARX_SPEELS_GetMaxRect("TERA"); ARX_SPEELS_GetMaxRect("VISTA"); ARX_SPEELS_GetMaxRect("VITAE"); ARX_SPEELS_GetMaxRect("YOK"); ARX_SPEELS_GetMaxRect("AKBAA"); } //----------------------------------------------------------------------------- void ARX_SPELLS_Init() { long i; for (i = 0; i < MAX_SPELLS; i++) { spells[i].tolive = 0; spells[i].exist = FALSE; spells[i].pSpellFx = NULL; } } void ARX_SPELLS_CancelAll() { long i; for (i = 0; i < MAX_SPELLS; i++) { if (spells[i].exist) { spells[i].tolive = 0; } } ARX_SPELLS_Update(NULL); ARX_SPELLS_RemoveAllSpellsOn(inter.iobj[0]); inter.iobj[0]->speed_modif=0; } // Clears All Spells. void ARX_SPELLS_ClearAll() { long i; for (i = 0; i < MAX_SPELLS; i++) { if (spells[i].exist) { spells[i].tolive = 0; spells[i].exist = FALSE; if (spells[i].pSpellFx) { delete spells[i].pSpellFx; spells[i].pSpellFx = NULL; } } } for (i = 0; i < inter.nbmax; i++) if (inter.iobj[i]) ARX_SPELLS_RemoveAllSpellsOn(inter.iobj[i]); } // Obtains a Free Spell slot long ARX_SPELLS_GetFree() { for (long i = 0; i < MAX_SPELLS; i++) { if (spells[i].exist == FALSE) { spells[i].longinfo = spells[i].longinfo2 = -1; spells[i].misc=NULL; return i; } } return -1; } // Checks for an existing instance of this spelltype BOOL ARX_SPELLS_ExistAnyInstance(const long &typ) { for (long i = 0; i < MAX_SPELLS; i++) if (spells[i].exist && (spells[i].type==typ)) return TRUE; return FALSE; } long ARX_SPELLS_GetInstance(const long &typ) { for (long i = 0; i < MAX_SPELLS; i++) if (spells[i].exist && (spells[i].type==typ)) return i; return -1; } long ARX_SPELLS_GetInstanceForThisCaster(const long &typ, const long &caster) { for (long i(0); i < MAX_SPELLS; i++) if (spells[i].exist && (spells[i].type == typ) && (spells[i].caster == caster)) return i; return -1; } BOOL ARX_SPELLS_ExistAnyInstanceForThisCaster(const long &typ, const long &caster) { for (long i(0); i < MAX_SPELLS; i++) if (spells[i].exist && (spells[i].type == typ) && (spells[i].caster == caster)) return TRUE; return FALSE; } // Plays the sound of aborted spell void ARX_SPELLS_AbortSpellSound() { ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE); } // Plays the sound of Fizzling spell void ARX_SPELLS_Fizzle(const long &num) { if (num < 0) ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE); // player fizzle else { spells[num].tolive = 0; if (spells[num].caster >= 0) ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE, &spells[num].caster_pos); } } void ARX_SPELLS_FizzleAllSpellsFromCaster(long num_caster) { for (long i(0); i < MAX_SPELLS; i++) { if ( (spells[i].exist) && (spells[i].caster == num_caster) ) { spells[i].tolive=0; } } } // Plays the sound of Fizzling spell plus "NO MANA" speech void ARX_SPELLS_FizzleNoMana(const long &num) { if (num < 0) return; if (spells[num].caster >= 0) { spells[num].tolive = 0; ARX_SPELLS_Fizzle(num); } } PRECAST_STRUCT Precast[MAX_PRECAST]; void ARX_SPELLS_Precast_Reset() { for (long i = 0; i < MAX_PRECAST; i++) Precast[i].typ = -1; } void ARX_SPELLS_Precast_Add(const long &typ, const long _level,long flags,long duration) { long found=-1; for (long i = 0; i < MAX_PRECAST; i++) if (Precast[i].typ == -1) { found = i; break; } if (found == -1) { for (long i = 1; i < MAX_PRECAST; i++) memcpy(&Precast[i - 1], &Precast[i],sizeof(PRECAST_STRUCT)); found = MAX_PRECAST - 1; } Precast[found].typ = typ; Precast[found].level = _level; Precast[found].launch_time = 0; Precast[found].flags = flags; Precast[found].duration = duration; } unsigned long LAST_PRECAST_TIME=0; long PrecastCheckCanPayMana(long num, float cost, bool _bSound = true) { if (num<0) return 0; if (Precast[num].flags & SPELLCAST_FLAG_NOMANA) return 1; if (player.mana>=cost) { return 1; } ARX_SPELLS_FizzleNoMana(num); if (_bSound) { ARX_SPEECH_AddLocalised(NULL, "[player_cantcast]"); ARX_SPEECH_AddSpeech( inter.iobj[0], "[player_cantcast]", PARAM_LOCALISED, ANIM_TALK_NEUTRAL); } return 0; } void ARX_SPELLS_Precast_Launch(const long &num) { if (ARXTime>=LAST_PRECAST_TIME+1000) { int iNumSpells=Precast[num].typ; float cost=ARX_SPELLS_GetManaCost(iNumSpells,-1); if( (iNumSpells>=0) && (!PrecastCheckCanPayMana(num,cost) ) ) return; LAST_PRECAST_TIME = ARXTimeUL(); if ((Precast[num].typ>=0) && (Precast[num].launch_time==0)) { Precast[num].launch_time = ARXTimeUL(); ARX_SOUND_PlaySFX(SND_SPELL_CREATE_FIELD); } } } void ARX_SPELLS_Precast_Check() { for (long i = 0; i < MAX_PRECAST; i++) { if ((Precast[i].typ>=0) && (Precast[i].launch_time>0) &&(ARXTime>=Precast[i].launch_time)) { ANIM_USE *ause1 = &inter.iobj[0]->animlayer[1]; if (player.Interface & INTER_COMBATMODE) { WILLRETURNTOCOMBATMODE=1; ARX_INTERFACE_Combat_Mode(0); bGToggleCombatModeWithKey=false; ResetAnim(&inter.iobj[0]->animlayer[1]); inter.iobj[0]->animlayer[1].flags&=~EA_LOOP; } if ((ause1->cur_anim) && (ause1->cur_anim==inter.iobj[0]->anims[ANIM_CAST])) { if (ause1->ctime>ause1->cur_anim->anims[ause1->altidx_cur]->anim_time-550) { ARX_SPELLS_Launch( Precast[i].typ, 0, Precast[i].flags | SPELLCAST_FLAG_LAUNCHPRECAST, Precast[i].level, -1, Precast[i].duration); Precast[i].typ = -1; for (long li=i; li < MAX_PRECAST - 1; li++) { if (Precast[li + 1].typ != -1) { memcpy(&Precast[li], &Precast[li + 1], sizeof(PRECAST_STRUCT)); Precast[li + 1].typ = -1; } } } } else ARX_SPELLS_Precast_Launch2(i); } } } void ARX_SPELLS_Precast_Launch2(const long &num) { ANIM_USE *ause1 = &inter.iobj[0]->animlayer[1]; AcquireLastAnim(inter.iobj[0]); FinishAnim(inter.iobj[0], ause1->cur_anim); ANIM_Set(ause1, inter.iobj[0]->anims[ANIM_CAST]); } typedef struct { long typ; long source; long flags; long level; long target; long duration; } TARGETING_SPELL; TARGETING_SPELL t_spell; long LOOKING_FOR_SPELL_TARGET=0; unsigned long LOOKING_FOR_SPELL_TARGET_TIME=0; void ARX_SPELLS_CancelSpellTarget() { t_spell.typ=-1; LOOKING_FOR_SPELL_TARGET=0; } void ARX_SPELLS_LaunchSpellTarget(INTERACTIVE_OBJ * io) { long num=GetInterNum(io); if (num>=0) { long type=t_spell.typ; long source=t_spell.source; long flags=t_spell.flags; long level=t_spell.level; long duration=t_spell.duration; ARX_SPELLS_Launch(type, source, flags, level, num, duration); } } extern long FINAL_RELEASE; //----------------------------------------------------------------------------- float ARX_SPELLS_GetManaCost(long _lNumSpell,long lNumSpellTab) { float Player_Magic_Level; Player_Magic_Level = (float) player.Full_Skill_Casting + player.Full_Attribute_Mind; Player_Magic_Level= __max(1,Player_Magic_Level*DIV10); Player_Magic_Level= __min(10,Player_Magic_Level); switch (_lNumSpell) { //----------------------------- case SPELL_MAGIC_SIGHT: return 0.3f; break; case SPELL_MAGIC_MISSILE: if (lNumSpellTab<0) return Player_Magic_Level; return spells[lNumSpellTab].caster_level; break; case SPELL_IGNIT: return 1.f; break; case SPELL_DOUSE: return 1.f; break; case SPELL_ACTIVATE_PORTAL: return 2.f; break; //----------------------------- case SPELL_HEAL: return 4.f; break; case SPELL_DETECT_TRAP: return 0.03f; break; case SPELL_ARMOR: return 0.01f; break; case SPELL_LOWER_ARMOR: return 0.01f; break; case SPELL_HARM: return 0.4f; break; //----------------------------- case SPELL_SPEED: return 0.01f; break; case SPELL_DISPELL_ILLUSION: return 7.f; break; case SPELL_FIREBALL: if (lNumSpellTab<0) return Player_Magic_Level*3.f; return 3.f*spells[lNumSpellTab].caster_level; break; case SPELL_CREATE_FOOD: return 5.f; break; case SPELL_ICE_PROJECTILE: if (lNumSpellTab<0) return Player_Magic_Level*1.5f; return 1.5f*spells[lNumSpellTab].caster_level; break; //---------------------------- case SPELL_BLESS: return 0.01f; break; case SPELL_DISPELL_FIELD: return 7.f; break; case SPELL_FIRE_PROTECTION: return 1.f; break; case SPELL_TELEKINESIS: return 0.001f; break; case SPELL_CURSE: return 0.001f; break; case SPELL_COLD_PROTECTION: return 1.f; break; //----------------------------- case SPELL_RUNE_OF_GUARDING: return 9.f; break; case SPELL_LEVITATE: return 1.f; break; case SPELL_CURE_POISON: return 10.f; break; case SPELL_REPEL_UNDEAD: return 18.f; break; case SPELL_POISON_PROJECTILE: if (lNumSpellTab<0) return Player_Magic_Level*2.f; return 2.f*spells[lNumSpellTab].caster_level; break; //----------------------------- case SPELL_RISE_DEAD: return 12.f; break; case SPELL_PARALYSE: if (lNumSpellTab<0) return Player_Magic_Level*3.f; return 3.f*spells[lNumSpellTab].caster_level; break; case SPELL_CREATE_FIELD: return 1.2f; break; case SPELL_DISARM_TRAP: return 15.f; break; case SPELL_SLOW_DOWN: return 1.2f; break; //----------------------------- case SPELL_FLYING_EYE: return 4.f; break; case SPELL_FIRE_FIELD: return 15.f; break; case SPELL_ICE_FIELD: return 15.f; break; case SPELL_LIGHTNING_STRIKE: if (lNumSpellTab<0) return Player_Magic_Level*6.f; return 6.f*spells[lNumSpellTab].caster_level; break; case SPELL_CONFUSE: if (lNumSpellTab<0) return Player_Magic_Level*0.1f; return 0.1f*spells[lNumSpellTab].caster_level; break; //----------------------------- case SPELL_INVISIBILITY: return 3.f; break; case SPELL_MANA_DRAIN: return 0.4f; break; case SPELL_EXPLOSION: return 45.f; break; case SPELL_ENCHANT_WEAPON: return 35.f; break; case SPELL_LIFE_DRAIN: return 3.f;//0.9f; //0.4f; break; //----------------------------- case SPELL_SUMMON_CREATURE: if (lNumSpellTab<0) { if(Player_Magic_Level>=9) return 80.f; } if(spells[lNumSpellTab].caster_level>=9) return 80.f; return 20.f; break; case SPELL_NEGATE_MAGIC: return 2.f; break; case SPELL_INCINERATE: return 40.f; break; case SPELL_MASS_PARALYSE: if (lNumSpellTab<0) return Player_Magic_Level*3.f; return 3.f*spells[lNumSpellTab].caster_level; break; //---------------------------- case SPELL_MASS_LIGHTNING_STRIKE: if (lNumSpellTab<0) return Player_Magic_Level*8.f; return 8.f*spells[lNumSpellTab].caster_level; break; case SPELL_CONTROL_TARGET: return 40.f; break; case SPELL_FREEZE_TIME: return 60.f; break; case SPELL_MASS_INCINERATE: return 160.f; break; case SPELL_FAKE_SUMMON: if (lNumSpellTab<0) { if(Player_Magic_Level>=9) return 80.f; } if(spells[lNumSpellTab].caster_level>=9) return 80.f; return 20.f; break; case SPELL_COUNT: return 0.f; break; //----------------------------- case SPELL_TELEPORT: return 10.f; break; default: return 0.f; } } //----------------------------------------------------------------------------- // Function used to launch a spell, returns Created Spell Ident long ARX_SPELLS_Launch( const long& typ, const long& source, const long& flagss, const long& levell, const long& target, const long& duration) //const long &netspell) { long flags = flagss; long level = levell; long i; if ( cur_rf == 3 ) { flags |= SPELLCAST_FLAG_NOCHECKCANCAST | SPELLCAST_FLAG_NOMANA; level += 2; } if ( sp_max ) { level = __max( level, 15 ); } if ( ( source == 0 ) && ( FINAL_RELEASE ) ) if ( !( flags & SPELLCAST_FLAG_NOCHECKCANCAST ) ) { for ( i = 0 ; i < MAX_SPELL_SYMBOLS ; i++ ) { if ( SpellSymbol[i] != 255 ) { if ( !( player.rune_flags & ( 1 << SpellSymbol[i] ) ) ) { ARX_SOUND_PlaySpeech( "player_cantcast" ); CurrSpellSymbol = 0; ARX_SPELLS_ResetRecognition(); return -1; } } } } float Player_Magic_Level = 0; if ( !source ) { ARX_SPELLS_ResetRecognition(); if ( player.SpellToMemorize.bSpell ) { CurrSpellSymbol = 0; player.SpellToMemorize.bSpell = false; } ARX_PLAYER_ComputePlayerFullStats(); if ( level == -1 ) { Player_Magic_Level = (float) player.Full_Skill_Casting + player.Full_Attribute_Mind; Player_Magic_Level = __max( 1, Player_Magic_Level * DIV10 ); Player_Magic_Level = __min( 10, Player_Magic_Level ); } else { Player_Magic_Level = ARX_CLEAN_WARN_CAST_FLOAT(level); } } ARX_CHECK( !( source && (flags & SPELLCAST_FLAG_PRECAST) ) ); if ( flags & SPELLCAST_FLAG_PRECAST ) { int l = level; if (l <= 0) { ARX_CHECK_INT(Player_Magic_Level); l = ARX_CLEAN_WARN_CAST_INT(Player_Magic_Level); } long flgs=flags; flgs&=~SPELLCAST_FLAG_PRECAST; ARX_SPELLS_Precast_Add( typ, l, flgs, duration); return -2; } if ( flags & SPELLCAST_FLAG_NOMANA ) { Player_Magic_Level = ARX_CLEAN_WARN_CAST_FLOAT(level); } static TextureContainer * tc4 = MakeTCFromFile("Graph\\Particles\\smoke.bmp"); if ((target < 0) && ( source == 0 ) ) switch ( typ ) { case SPELL_LOWER_ARMOR: case SPELL_CURSE: case SPELL_PARALYSE: case SPELL_INCINERATE: case SPELL_SLOW_DOWN: case SPELL_CONFUSE: { LOOKING_FOR_SPELL_TARGET_TIME = ARXTimeUL(); LOOKING_FOR_SPELL_TARGET = 1; t_spell.typ = typ; t_spell.source = source; t_spell.flags = flags; t_spell.level = level; t_spell.target = target; t_spell.duration = duration; return -1; } case SPELL_ENCHANT_WEAPON: { LOOKING_FOR_SPELL_TARGET_TIME = ARXTimeUL(); LOOKING_FOR_SPELL_TARGET = 2; t_spell.typ = typ; t_spell.source = source; t_spell.flags = flags; t_spell.level = level; t_spell.target = target; t_spell.duration = duration; return -1; } break; case SPELL_CONTROL_TARGET: { long tcount = 0; EERIE_3D cpos; if ( !ValidIONum( source ) ) return -1; Vector_Copy( &cpos, &inter.iobj[source]->pos ); for ( long ii = 1 ; ii < inter.nbmax ; ii++ ) { INTERACTIVE_OBJ * ioo = inter.iobj[ii]; if ( ( ioo ) && ( ioo->ioflags & IO_NPC ) && ( ioo->_npcdata->life > 0.f ) && ( ioo->show == SHOW_FLAG_IN_SCENE ) && ( IsIOGroup( ioo, "DEMON") ) && ( EEDistance3D(&ioo->pos,&cpos) < 900.f ) ) { tcount++; } } if ( tcount == 0 ) { ARX_SOUND_PlaySFX( SND_MAGIC_FIZZLE, &cpos ); return -1; } ARX_SOUND_PlaySpeech( "Player_follower_attack" ); LOOKING_FOR_SPELL_TARGET_TIME = ARXTimeUL(); LOOKING_FOR_SPELL_TARGET = 1; t_spell.typ = typ; t_spell.source = source; t_spell.flags = flags; t_spell.level = level; t_spell.target = target; t_spell.duration = duration; return -1; } break; } if ( source == 0 ) { ARX_SPELLS_CancelSpellTarget(); } // Try to create a new spell instance i = ARX_SPELLS_GetFree(); if ( i < 0 ) { return -1; } if ( source >= 0 && source < inter.nbmax ) { if ( spellicons[typ].bAudibleAtStart ) { ARX_NPC_SpawnAudibleSound(&inter.iobj[source]->pos,inter.iobj[source]); } } spells[i].caster = source; // Caster... spells[i].target = target; // No target if <0 if ( target < 0 ) spells[i].target = TemporaryGetSpellTarget( &inter.iobj[spells[i].caster]->pos ); // Create hand position if a hand is defined if ( spells[i].caster == 0 ) { spells[i].hand_group = inter.iobj[spells[i].caster]->obj->fastaccess.primary_attach; } else { spells[i].hand_group = inter.iobj[spells[i].caster]->obj->fastaccess.left_attach; } if ( spells[i].hand_group != -1 ) { spells[i].hand_pos.x = inter.iobj[spells[i].caster]->obj->vertexlist3[spells[i].hand_group].v.x; spells[i].hand_pos.y = inter.iobj[spells[i].caster]->obj->vertexlist3[spells[i].hand_group].v.y; spells[i].hand_pos.z = inter.iobj[spells[i].caster]->obj->vertexlist3[spells[i].hand_group].v.z; } if ( !source ) { // Player source spells[i].caster_level = Player_Magic_Level; // Level of caster spells[i].caster_pos.x = player.pos.x; spells[i].caster_pos.y = player.pos.y; spells[i].caster_pos.z = player.pos.z; spells[i].caster_angle.x = player.angle.x; spells[i].caster_angle.y = player.angle.y; spells[i].caster_angle.z = player.angle.z; } else { // IO source spells[i].caster_level = level < 1 ? 1 : level > 10 ? 10 : ARX_CLEAN_WARN_CAST_FLOAT(level); spells[i].caster_pos.x = inter.iobj[source]->pos.x; spells[i].caster_pos.y = inter.iobj[source]->pos.y; spells[i].caster_pos.z = inter.iobj[source]->pos.z; spells[i].caster_angle.x = inter.iobj[source]->angle.x; spells[i].caster_angle.y = inter.iobj[source]->angle.y; spells[i].caster_angle.z = inter.iobj[source]->angle.z; } if (flags & SPELLCAST_FLAG_LAUNCHPRECAST) { spells[i].caster_level = ARX_CLEAN_WARN_CAST_FLOAT(level); } // Checks target if (target<0) // no target... targeted by sight { if (source==0) // no target... player spell targeted by sight { spells[i].target_pos.x=player.pos.x-EEsin(DEG2RAD(player.angle.b))*60.f; spells[i].target_pos.y=player.pos.y+EEsin(DEG2RAD(player.angle.a))*60.f; spells[i].target_pos.z=player.pos.z+EEcos(DEG2RAD(player.angle.b))*60.f; spells[i].target_angle.a=0.f; spells[i].target_angle.b=0.f; spells[i].target_angle.g=0.f; } else { spells[i].target_pos.x=inter.iobj[target]->pos.x-EEsin(DEG2RAD(inter.iobj[target]->angle.b))*60.f; spells[i].target_pos.y=inter.iobj[target]->pos.y-120.f; spells[i].target_pos.z=inter.iobj[target]->pos.z+EEcos(DEG2RAD(inter.iobj[target]->angle.b))*60.f; spells[i].target_angle.a=0.f; spells[i].target_angle.b=0.f; spells[i].target_angle.g=0.f; } } // player target else if (target==0) { spells[i].target_pos.x=player.pos.x; spells[i].target_pos.y=player.pos.x; spells[i].target_pos.z=player.pos.z; spells[i].target_angle.a=player.angle.a; spells[i].target_angle.b=player.angle.b; spells[i].target_angle.g=player.angle.g; } // IO target else { spells[i].target_pos.x=inter.iobj[target]->pos.x; spells[i].target_pos.y=inter.iobj[target]->pos.y; spells[i].target_pos.z=inter.iobj[target]->pos.z; spells[i].target_angle.a=inter.iobj[target]->angle.a; spells[i].target_angle.b=inter.iobj[target]->angle.b; spells[i].target_angle.g=inter.iobj[target]->angle.g; } // spell direction spells[i].vector_dir.x=spells[i].target_pos.x-spells[i].caster_pos.x; spells[i].vector_dir.y=spells[i].target_pos.y-spells[i].caster_pos.y; spells[i].vector_dir.z=spells[i].target_pos.z-spells[i].caster_pos.z; float t=Vector_Magnitude(&spells[i].vector_dir); if (t<=0) t=0.0001f; t=1.f/t; spells[i].vector_dir.x*=t; spells[i].vector_dir.y*=t; spells[i].vector_dir.z*=t; spells[i].flags=flags; spells[i].cumul=0; spells[i].pSpellFx=NULL; spells[i].type = typ; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); switch (typ) { //********************************************************************************************* // LEVEL 1 SPELLS ----------------------------------------------------------------------------- case SPELL_MAGIC_SIGHT: // Launching MAGIC_SIGHT if (ARX_SPELLS_ExistAnyInstanceForThisCaster(typ,spells[i].caster)) return -1; if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); spells[i].exist=TRUE; spells[i].fManaCostPerSecond=0.36f; spells[i].bDuration = true; if (duration>-1) spells[i].tolive=duration; else spells[i].tolive=6000000; SPELLCAST_Notify(i); ARX_SOUND_PlaySFX(SND_SPELL_VISION_START, &spells[i].caster_pos); if (spells[i].caster==0) { Project.improve = 1; spells[i].snd_loop = SND_SPELL_VISION_LOOP; ARX_SOUND_PlaySFX(spells[i].snd_loop, &spells[i].caster_pos, 1.0F, ARX_SOUND_PLAY_LOOPED); } break; //---------------------------------------------------------------------------------------------- case SPELL_MAGIC_MISSILE: // Launching MAGIC_MISSILE { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); spells[i].exist = TRUE; spells[i].tolive = 20000; CSpellFx *pCSpellFx = NULL; long number; if ( ( sp_max ) || ( cur_rf == 3 ) ) { ARX_CHECK_LONG(spells[i].caster_level); number = ARX_CLEAN_WARN_CAST_LONG( spells[i].caster_level ); } else { if ( spells[i].caster_level < 3 ) number = 1; else if ( spells[i].caster_level < 5 ) number = 2; else if ( spells[i].caster_level < 7 ) number = 3; else if ( spells[i].caster_level < 9 ) number = 4; else number=5; } pCSpellFx = new CMultiMagicMissile(GDevice,number); if (pCSpellFx != NULL) { EERIE_3D source_position,vector; pCSpellFx->spellinstance=i; Vector_Init(&source_position); Vector_Init(&vector); pCSpellFx->SetDuration((unsigned long) (6000)); pCSpellFx->Create(source_position, vector ); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------------------------- case SPELL_IGNIT:// Launching IGNIT { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); bool bLightInRadius = false; spells[i].exist = TRUE; spells[i].tolive = 20000; CSpellFx *pCSpellFx = NULL; pCSpellFx = new CIgnit(); CIgnit *pIgnit=(CIgnit *)pCSpellFx; if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; EERIE_3D target; if (spells[i].hand_group!=-1) { target.x=spells[i].hand_pos.x; target.y=spells[i].hand_pos.y; target.z=spells[i].hand_pos.z; } else { target.x=spells[i].caster_pos.x; target.y=spells[i].caster_pos.y-50.f; target.z=spells[i].caster_pos.z; } long id=GetFreeDynLight(); if (id!=-1) { DynLight[id].exist = 1; DynLight[id].intensity = 1.8f; DynLight[id].fallend = 450.f; DynLight[id].fallstart = 380.f; DynLight[id].rgb.r = 1.f; DynLight[id].rgb.g = 0.75f; DynLight[id].rgb.b = 0.5f; DynLight[id].pos.x = target.x; DynLight[id].pos.y = target.y; DynLight[id].pos.z = target.z; DynLight[id].duration = 300; } float fPerimeter = 400.0f + spells[i].caster_level*30.0f; pIgnit->Create(&target, fPerimeter, 500); CheckForIgnition(&target,fPerimeter,1,1); for (long ii=0;iiextras & EXTRAS_EXTINGUISHABLE) && ((spells[i].caster!=0) || ((spells[i].caster==0) && !(GLight[ii]->extras & EXTRAS_NO_IGNIT))) && ((GLight[ii]->extras & EXTRAS_SEMIDYNAMIC) || (GLight[ii]->extras & EXTRAS_SPAWNFIRE) || (GLight[ii]->extras & EXTRAS_SPAWNSMOKE) ) && (!GLight[ii]->status)) { float dist=EEDistance3D(&target,&GLight[ii]->pos); if (dist<=(pIgnit->GetPerimetre())) { pIgnit->AddLight(ii); bLightInRadius = true; } } } for (long n=0;neCurPos.x; sphere.origin.y=pCF->eCurPos.y; sphere.origin.z=pCF->eCurPos.z; sphere.radius=__max(spells[i].caster_level*2.f,12.f); if (EEDistance3D(&target,&sphere.origin)GetPerimetre()+sphere.radius) { spells[n].caster_level += 1; } } break; } } } } if (pCSpellFx) { spells[i].pSpellFx = pCSpellFx; CIgnit *pIgnit=(CIgnit *)pCSpellFx; spells[i].tolive = pIgnit->GetDuration(); } SPELLCAST_Notify(i); } break; //--------------------------------------------------------------------------------------------- case SPELL_DOUSE:// Launching DOUSE { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); bool bLightInRadius = false; spells[i].exist = TRUE; spells[i].tolive = 20000; CSpellFx *pCSpellFx = NULL; pCSpellFx = new CDoze(); CDoze *pDoze=(CDoze *)pCSpellFx; if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; EERIE_3D target; if (spells[i].hand_group>=0) { target.x=spells[i].hand_pos.x; target.y=spells[i].hand_pos.y; target.z=spells[i].hand_pos.z; } else { target.x=spells[i].caster_pos.x; target.y=spells[i].caster_pos.y-50.f; target.z=spells[i].caster_pos.z; } float fPerimeter = 400.0f + spells[i].caster_level*30.0f; pDoze->CreateDoze(&target, fPerimeter, 500); CheckForIgnition(&target,fPerimeter,0,1); for (long ii=0;iiextras & EXTRAS_EXTINGUISHABLE) && ((GLight[ii]->extras & EXTRAS_SEMIDYNAMIC) || (GLight[ii]->extras & EXTRAS_SPAWNFIRE) || (GLight[ii]->extras & EXTRAS_SPAWNSMOKE) ) && (GLight[ii]->status)) { float dist=EEDistance3D(&target,&GLight[ii]->pos); if (dist <= (pDoze->GetPerimetre())) { pDoze->AddLightDoze(ii); bLightInRadius = true; } } } if ((CURRENT_TORCH) && (EEDistance3D(&target,&player.pos)GetPerimetre())) { ARX_PLAYER_ClickedOnTorch(CURRENT_TORCH); } for (long n=0;neCurPos.x; sphere.origin.y=pCF->eCurPos.y; sphere.origin.z=pCF->eCurPos.z; sphere.radius=__max(spells[i].caster_level*2.f,12.f); if (EEDistance3D(&target,&sphere.origin)GetPerimetre()+sphere.radius) { spells[n].caster_level-=spells[i].caster_level; if (spells[n].caster_level<1) spells[n].tolive=0; } } break; case SPELL_FIRE_FIELD: { EERIE_3D pos; if (GetSpellPosition(&pos,n)) { if (EEDistance3D(&target,&pos)GetPerimetre()+200) { spells[n].caster_level-=spells[i].caster_level; if (spells[n].caster_level<1) spells[n].tolive=0; } } } break; } } } } if (pCSpellFx) { spells[i].pSpellFx = pCSpellFx; CDoze *pDoze=(CDoze *)pCSpellFx; spells[i].tolive = pDoze->GetDuration(); } SPELLCAST_Notify(i); } break; //--------------------------------------------------------------------------------------------- case SPELL_ACTIVATE_PORTAL:// Launching ACTIVATE_PORTAL { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); ARX_SOUND_PlayInterface(SND_SPELL_ACTIVATE_PORTAL); spells[i].exist = TRUE; spells[i].tolive = 20; SPELLCAST_Notify(i); } break; //************************************************************************************************* // LEVEL 2 SPELLS ----------------------------------------------------------------------------- case SPELL_HEAL:// Launching HEAL { // return No_MagicAllowed(); if (ARX_SPELLS_ExistAnyInstanceForThisCaster(typ,spells[i].caster)) return -1; if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); if (!(spells[i].flags & SPELLCAST_FLAG_NOSOUND)) ARX_SOUND_PlaySFX(SND_SPELL_HEALING, &spells[i].caster_pos); spells[i].exist = TRUE; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 0.4f*spells[i].caster_level; if (duration>-1) spells[i].tolive=duration; else spells[i].tolive=3500; CSpellFx *pCSpellFx = NULL; pCSpellFx = new CHeal(GDevice); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; pCSpellFx->Create(); pCSpellFx->SetDuration(spells[i].tolive); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } SPELLCAST_Notify(i); } break; //--------------------------------------------------------------------------------------------- case SPELL_DETECT_TRAP:// Launching DETECT_TRAP { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); long iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_DETECT_TRAP,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } if (spells[i].caster==0) if (!(spells[i].flags & SPELLCAST_FLAG_NOSOUND)) ARX_SOUND_PlayInterface(SND_SPELL_DETECT_TRAP); spells[i].snd_loop = SND_SPELL_DETECT_TRAP_LOOP; if (spells[i].caster==0) if (!(spells[i].flags & SPELLCAST_FLAG_NOSOUND)) ARX_SOUND_PlaySFX(spells[i].snd_loop, &spells[i].caster_pos, 1.0F, ARX_SOUND_PLAY_LOOPED); spells[i].exist = TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].tolive = 60000; spells[i].fManaCostPerSecond=0.4f; spells[i].bDuration = true; SPELLCAST_Notify(i); } break; //--------------------------------------------------------------------------------------------- case SPELL_ARMOR:// Launching ARMOR { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); long idx=ARX_SPELLS_GetSpellOn(inter.iobj[spells[i].target],SPELL_ARMOR); if (idx>=0) { spells[idx].tolive = 0; } long iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_LOWER_ARMOR,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_FIRE_PROTECTION,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_COLD_PROTECTION,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } if (spells[i].caster==0) spells[i].target=spells[i].caster; if (!(spells[i].flags & SPELLCAST_FLAG_NOSOUND)) ARX_SOUND_PlaySFX(SND_SPELL_ARMOR_START, &spells[i].target_pos); spells[i].snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_ARMOR_LOOP, &spells[i].caster_pos, 1.0F, ARX_SOUND_PLAY_LOOPED); spells[i].exist = TRUE; if (spells[i].caster==0) spells[i].tolive = 20000000; else spells[i].tolive = 20000; if (duration>-1) spells[i].tolive=duration; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 0.2f*spells[i].caster_level; CSpellFx *pCSpellFx = NULL; pCSpellFx = new CArmor(); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; CArmor *pArmor=(CArmor *)pCSpellFx; pArmor->Create(spells[i].tolive, 0); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pArmor->GetDuration(); } ARX_SPELLS_AddSpellOn(spells[i].target,i); SPELLCAST_Notify(i); } break; //------------------------------------------------------------------------------------------------ case SPELL_LOWER_ARMOR:// Launching LOWER_ARMOR { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); long idx=ARX_SPELLS_GetSpellOn(inter.iobj[spells[i].target],SPELL_LOWER_ARMOR); if (idx>=0) { spells[idx].tolive = 0; } if (spells[i].target<0) return -1; long iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_ARMOR,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_FIRE_PROTECTION,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_COLD_PROTECTION,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } if (!(spells[i].flags & SPELLCAST_FLAG_NOSOUND)) ARX_SOUND_PlaySFX(SND_SPELL_ARMOR_START, &spells[i].caster_pos); spells[i].exist = TRUE; if (spells[i].caster==0) spells[i].tolive = 20000000; else spells[i].tolive = 20000; if (duration>-1) spells[i].tolive=duration; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 0.2f*spells[i].caster_level; CSpellFx *pCSpellFx = NULL; pCSpellFx = new CLowerArmor(); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; CLowerArmor *pLowerArmor=(CLowerArmor *)pCSpellFx; pLowerArmor->Create(spells[i].tolive, spells[i].target); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } ARX_SPELLS_AddSpellOn(spells[i].target,i); SPELLCAST_Notify(i); } break; //------------------------------------------------------------------------------------------------ case SPELL_HARM:// Launching HARM { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); if (!(spells[i].flags & SPELLCAST_FLAG_NOSOUND)) ARX_SOUND_PlaySFX(SND_SPELL_HARM, &spells[i].caster_pos); spells[i].snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_MAGICAL_SHIELD, &spells[i].caster_pos, 1.0F, ARX_SOUND_PLAY_LOOPED); long iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_LIFE_DRAIN,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_MANA_DRAIN,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } spells[i].exist=TRUE; spells[i].tolive=6000000; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 0.4f; spells[i].longinfo=ARX_DAMAGES_GetFree(); if (spells[i].longinfo!=-1) { damages[spells[i].longinfo].radius=150.f; damages[spells[i].longinfo].damages=4.f;//2.f; damages[spells[i].longinfo].area=DAMAGE_FULL; damages[spells[i].longinfo].duration=100000000; damages[spells[i].longinfo].source=spells[i].caster; damages[spells[i].longinfo].flags=DAMAGE_FLAG_DONT_HURT_SOURCE | DAMAGE_FLAG_FOLLOW_SOURCE | DAMAGE_FLAG_ADD_VISUAL_FX; damages[spells[i].longinfo].type=DAMAGE_TYPE_FAKEFIRE | DAMAGE_TYPE_MAGICAL; damages[spells[i].longinfo].exist=TRUE; } spells[i].longinfo2=GetFreeDynLight(); if (spells[i].longinfo2 != -1) { long id = spells[i].longinfo2; DynLight[id].exist = 1; DynLight[id].intensity = 2.3f; DynLight[id].fallend = 700.f; DynLight[id].fallstart = 500.f; DynLight[id].rgb.r = 1.0f; DynLight[id].rgb.g = 0.0f; DynLight[id].rgb.b = 0.0f; DynLight[id].pos.x = spells[i].caster_pos.x; DynLight[id].pos.y = spells[i].caster_pos.y; DynLight[id].pos.z = spells[i].caster_pos.z; } if (duration>-1) spells[i].tolive=duration; SPELLCAST_Notify(i); } break; //********************************************************************************************** // LEVEL 3 SPELLS ----------------------------------------------------------------------------- case SPELL_SPEED:// Launching SPEED { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); spells[i].bDuration = true; spells[i].fManaCostPerSecond = 2.f; ARX_SOUND_PlaySFX(SND_SPELL_SPEED_START, &spells[i].caster_pos); if (spells[i].caster==0) { spells[i].target = spells[i].caster; spells[i].snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_SPEED_LOOP, &spells[i].caster_pos, 1.0F, ARX_SOUND_PLAY_LOOPED); } spells[i].exist = TRUE; if (spells[i].caster==0) spells[i].tolive = 200000000; else spells[i].tolive = 20000; if (duration>-1) spells[i].tolive=duration; CSpellFx *pCSpellFx = NULL; pCSpellFx = new CSpeed(); CSpeed *pSpeed = (CSpeed *)pCSpellFx; if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; pSpeed->Create(spells[i].target, spells[i].tolive); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pSpeed->GetDuration(); } SPELLCAST_Notify(i); ARX_SPELLS_AddSpellOn(spells[i].target,i); if ((spells[i].caster>=0) && (spells[i].targetspeed_modif+=spells[i].caster_level*DIV10; } } break; //-------------------------------------------------------------------------------------------------- case SPELL_DISPELL_ILLUSION:// Launching DISPELL_ILLUSION (REVEAL) { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); ARX_SOUND_PlaySFX(SND_SPELL_DISPELL_ILLUSION); spells[i].exist = TRUE; spells[i].tolive = 1000; SPELLCAST_Notify(i); for (long n=0;nspells[i].caster_level) continue; switch (spells[n].type) { case SPELL_INVISIBILITY: { if (ValidIONum(spells[n].target) && ValidIONum(spells[i].caster)) { if (EEDistance3D(&inter.iobj[spells[n].target]->pos, &inter.iobj[spells[i].caster]->pos) <1000) { spells[n].tolive=0; } } break; } } } } break; //---------------------------------------------------------------------------------------------- case SPELL_FIREBALL:// Launching FIREBALL { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); spells[i].exist = TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].tolive = 20000; CSpellFx *pCSpellFx = NULL; pCSpellFx = new CFireBall(); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; EERIE_3D target; if (spells[i].caster!=0) spells[i].hand_group=-1; if (spells[i].hand_group>=0) { target.x=spells[i].hand_pos.x; target.y=spells[i].hand_pos.y; target.z=spells[i].hand_pos.z; } else { target.x=spells[i].caster_pos.x; target.y=spells[i].caster_pos.y; target.z=spells[i].caster_pos.z; if ((ValidIONum(spells[i].caster)) && (inter.iobj[spells[i].caster]->ioflags & IO_NPC)) { target.x-=EEsin(DEG2RAD(inter.iobj[spells[i].caster]->angle.b))*30.f; target.y-=80.f; target.z+=EEcos(DEG2RAD(inter.iobj[spells[i].caster]->angle.b))*30.f; } } pCSpellFx->SetDuration((unsigned long) (6000)); CFireBall * cf=(CFireBall *)pCSpellFx; if (spells[i].caster==0) cf->Create(target,MAKEANGLE(player.angle.b),player.angle.a,spells[i].caster_level); else { float angle; if ((spells[i].target>=0) && (spells[i].targetpos.x ; eCurPos.y = inter.iobj[spells[i].caster]->pos.y; eCurPos.z = inter.iobj[spells[i].caster]->pos.z ; if ((ValidIONum(spells[i].caster)) && (inter.iobj[spells[i].caster]->ioflags & IO_NPC)) { eCurPos.y-=80.f; } INTERACTIVE_OBJ * _io=inter.iobj[spells[i].caster]; if (ValidIONum(_io->targetinfo)) { EERIE_3D * p1=&eCurPos; EERIE_3D * p2=&inter.iobj[_io->targetinfo]->pos; angle=(RAD2DEG(GetAngle(p1->y,p1->z,p2->y,p2->z+TRUEDistance2D(p2->x,p2->z,p1->x,p1->z))));//alpha entre orgn et dest; } cf->Create(target,MAKEANGLE(inter.iobj[spells[i].caster]->angle.b),angle,spells[i].caster_level); } } if (pCSpellFx) { spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } ARX_SOUND_PlaySFX(SND_SPELL_FIRE_LAUNCH, &spells[i].caster_pos); spells[i].snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_FIRE_WIND, &spells[i].caster_pos, 1.0F, ARX_SOUND_PLAY_LOOPED); SPELLCAST_Notify(i); } break; //------------------------------------------------------------------------------------------------- case SPELL_CREATE_FOOD:// Launching CREATE_FOOD { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); ARX_SOUND_PlaySFX(SND_SPELL_CREATE_FOOD, &spells[i].caster_pos); spells[i].exist = TRUE; spells[i].tolive = 3500; if (duration>-1) spells[i].tolive=duration; CSpellFx *pCSpellFx = NULL; if ((spells[i].caster==0) || (spells[i].target==0)) player.hunger=100; pCSpellFx = new CCreateFood(GDevice); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; pCSpellFx->Create(); pCSpellFx->SetDuration(spells[i].tolive); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------------------------- case SPELL_ICE_PROJECTILE:// Launching ICE_PROJECTILE { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); ARX_SOUND_PlaySFX(SND_SPELL_ICE_PROJECTILE_LAUNCH, &spells[i].caster_pos); spells[i].exist = TRUE; spells[i].tolive = 4200; CSpellFx *pCSpellFx = NULL; pCSpellFx = new CIceProjectile(GDevice); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; EERIE_3D target; if (spells[i].caster==0) { target.x = player.pos.x - EEsin(DEG2RAD(MAKEANGLE(player.angle.b)))*150.0f; target.y = player.pos.y+160; target.z = player.pos.z + EEcos(DEG2RAD(MAKEANGLE(player.angle.b)))*150.0f; CIceProjectile *pIP = (CIceProjectile*)pCSpellFx; pIP->Create(target, MAKEANGLE(player.angle.b), spells[i].caster_level); } else { target.x = inter.iobj[spells[i].caster]->pos.x - EEsin(DEG2RAD(MAKEANGLE(inter.iobj[spells[i].caster]->angle.b)))*150.0f; target.y = inter.iobj[spells[i].caster]->pos.y; target.z = inter.iobj[spells[i].caster]->pos.z + EEcos(DEG2RAD(MAKEANGLE(inter.iobj[spells[i].caster]->angle.b)))*150.0f; CIceProjectile *pIP = (CIceProjectile*)pCSpellFx; pIP->Create(target, MAKEANGLE(inter.iobj[spells[i].caster]->angle.b), spells[i].caster_level); } pCSpellFx->SetDuration(spells[i].tolive); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } SPELLCAST_Notify(i); } break; //*********************************************************************************************** // LEVEL 4 SPELLS ----------------------------------------------------------------------------- case SPELL_BLESS:// Launching BLESS { if (ARX_SPELLS_ExistAnyInstance(typ)) { return -1; } if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); if (spells[i].caster==0) spells[i].target=0; long iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_BLESS,spells[i].target); if (iCancel > -1) { spells[iCancel].tolive = 0; } ARX_SOUND_PlaySFX(SND_SPELL_BLESS); spells[i].exist = TRUE; spells[i].tolive = 2000000; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 0.5f*spells[i].caster_level*0.6666f; if (duration>-1) spells[i].tolive=duration; CSpellFx *pCSpellFx = NULL; pCSpellFx = new CBless(GDevice); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; EERIE_3D target; target.x = inter.iobj[spells[i].caster]->pos.x; target.y = inter.iobj[spells[i].caster]->pos.y; target.z = inter.iobj[spells[i].caster]->pos.z; pCSpellFx->Create(target, MAKEANGLE(player.angle.b)); pCSpellFx->SetDuration(20000); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } ARX_SPELLS_AddSpellOn(spells[i].target,i); SPELLCAST_Notify(i); } break; //----------------------------------------------------------------------------------------------- case SPELL_DISPELL_FIELD:// Launching DISPELL_FIELD { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); SPELLCAST_Notify(i); spells[i].tolive = 10; EERIE_3D target; target.x = inter.iobj[spells[i].caster]->pos.x; target.y = inter.iobj[spells[i].caster]->pos.y; target.z = inter.iobj[spells[i].caster]->pos.z; long valid=0; long dispelled=0; for (long n=0;neSrc.x; sphere.origin.y=pCreateField->eSrc.y; sphere.origin.z=pCreateField->eSrc.z; sphere.radius=400.f; if ((spells[i].caster!=0) || (spells[n].caster==0)) { if (EEDistance3D(&target,&sphere.origin)pos.x; sphere.origin.y=pFireField->pos.y; sphere.origin.z=pFireField->pos.z; sphere.radius=400.f; if (EEDistance3D(&target,&sphere.origin)eSrc.x; sphere.origin.y=pIceField->eSrc.y; sphere.origin.z=pIceField->eSrc.z; sphere.radius=400.f; if (EEDistance3D(&target,&sphere.origin)dispelled) { ARX_SPEECH_AddSpeech(inter.iobj[0],"[player_not_skilled_enough]",PARAM_LOCALISED,ANIM_TALK_NEUTRAL,ARX_SPEECH_FLAG_NOTEXT); if (dispelled>0) { ARX_SOUND_PlaySFX(SND_SPELL_DISPELL_FIELD); } } else if (valid>0) { ARX_SOUND_PlaySFX(SND_SPELL_DISPELL_FIELD); } else { ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE, &spells[i].caster_pos); } } break; //----------------------------------------------------------------------------------------------- case SPELL_FIRE_PROTECTION:// Launching FIRE_PROTECTION { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); long idx=ARX_SPELLS_GetSpellOn(inter.iobj[spells[i].target],SPELL_FIRE_PROTECTION); if (idx>=0) { spells[idx].tolive = 0; } ARX_SOUND_PlaySFX(SND_SPELL_FIRE_PROTECTION); if (duration>-1) spells[i].tolive=duration; long iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_ARMOR,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_LOWER_ARMOR,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_COLD_PROTECTION,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } spells[i].exist = TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].tolive = 2000000; if (spells[i].caster==0) spells[i].target=0; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 1.f; CSpellFx *pCSpellFx = NULL; pCSpellFx = new CFireProtection(); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; CFireProtection *pFP=(CFireProtection *)pCSpellFx; pFP->Create(spells[i].tolive, spells[i].target); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } ARX_SPELLS_AddSpellOn(spells[i].target,i); SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------------------------- case SPELL_COLD_PROTECTION:// Launching COLD_PROTECTION { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); long idx=ARX_SPELLS_GetSpellOn(inter.iobj[spells[i].target],SPELL_COLD_PROTECTION); if (idx>=0) { spells[idx].tolive = 0; } long iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_ARMOR,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_LOWER_ARMOR,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_FIRE_PROTECTION,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } ARX_SOUND_PlaySFX(SND_SPELL_COLD_PROTECTION_START); if (spells[i].caster==0) spells[i].target=0; spells[i].exist = TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].tolive = 2000000; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 1.f; if (duration>-1) spells[i].tolive=duration; CSpellFx *pCSpellFx = new CColdProtection(); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; CColdProtection *pCP= (CColdProtection *)pCSpellFx; pCP->Create(spells[i].tolive, spells[i].target); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } spells[i].snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_COLD_PROTECTION_LOOP, &spells[i].caster_pos, 1.0F, ARX_SOUND_PLAY_LOOPED); ARX_SPELLS_AddSpellOn(spells[i].target,i); SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------------------------- case SPELL_TELEKINESIS:// Launching TELEKINESIS { if (ARX_SPELLS_ExistAnyInstanceForThisCaster(SPELL_TELEKINESIS,spells[i].caster)) return -1; if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); spells[i].exist=TRUE; spells[i].tolive=6000000; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 0.9f; if (duration>-1) spells[i].tolive=duration; if (spells[i].caster==0) Project.telekinesis=1; ARX_SOUND_PlaySFX(SND_SPELL_TELEKINESIS_START, &spells[i].caster_pos); SPELLCAST_Notify(i); } break; //----------------------------------------------------------------------------------------------- case SPELL_CURSE:// Launching CURSE { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); long iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_CURSE,spells[i].target); if (iCancel > -1) { spells[iCancel].tolive = 0; } ARX_SOUND_PlaySFX(SND_SPELL_CURSE, &spells[i].caster_pos); spells[i].exist = TRUE; spells[i].tolive = 2000000; if (duration>-1) spells[i].tolive=duration; CSpellFx *pCSpellFx = NULL; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 0.5f*spells[i].caster_level; pCSpellFx = new CCurse(GDevice); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; EERIE_3D target; target.x=spells[i].target_pos.x; target.y=spells[i].target_pos.y; if ((spells[i].target>=0) && (inter.iobj[spells[i].target])) { if (spells[i].target==0) target.y-=200.f; else target.y+=inter.iobj[spells[i].target]->physics.cyl.height-50.f; } target.z=spells[i].target_pos.z; pCSpellFx->Create(target, MAKEANGLE(player.angle.b)); pCSpellFx->SetDuration(spells[i].tolive); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } ARX_SPELLS_AddSpellOn(spells[i].target,i); SPELLCAST_Notify(i); } break; //********************************************************************* // LEVEL 5 SPELLS ----------------------------------------------------------------------------- case SPELL_RUNE_OF_GUARDING: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); long iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_RUNE_OF_GUARDING,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } ARX_SOUND_PlaySFX(SND_SPELL_RUNE_OF_GUARDING); spells[i].exist = TRUE; spells[i].tolive = 99999999; if (duration>-1) spells[i].tolive=duration; CSpellFx *pCSpellFx = new CRuneOfGuarding(GDevice); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; EERIE_3D target; target.x = inter.iobj[spells[i].caster]->pos.x; target.y = inter.iobj[spells[i].caster]->pos.y; target.z = inter.iobj[spells[i].caster]->pos.z; pCSpellFx->Create(target, 0); pCSpellFx->SetDuration(spells[i].tolive); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------- case SPELL_LEVITATE: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); long iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_LEVITATE,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } ARX_SOUND_PlaySFX(SND_SPELL_LEVITATE_START); spells[i].exist = TRUE; spells[i].tolive = 2000000000; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 1.f; if (duration>-1) spells[i].tolive=duration; CSpellFx *pCSpellFx = new CLevitate(); if (pCSpellFx != NULL) { CLevitate *pLevitate=(CLevitate *)pCSpellFx; pCSpellFx->spellinstance=i; EERIE_3D target; if ( (spells[i].caster==0) || (spells[i].target==0) ) { target.x=player.pos.x; target.y=player.pos.y+150.f; target.z=player.pos.z; spells[i].target = 0; spells[i].tolive = 200000000; player.levitate=1; } else { target.x=inter.iobj[spells[i].target]->pos.x; target.y = inter.iobj[spells[i].target]->pos.y; target.z=inter.iobj[spells[i].target]->pos.z; } pLevitate->Create(16,50.f,100.f,80.f,&target,spells[i].tolive); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } ARX_SPELLS_AddSpellOn(spells[i].target,i); SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------- case SPELL_CURE_POISON: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); float cure=spells[i].caster_level*10; if (spells[i].caster==0) spells[i].target=0; if (spells[i].target==0) { player.poison-=cure; if (player.poison<0.f) player.poison=0; ARX_SOUND_PlaySFX(SND_SPELL_CURE_POISON); } else { if (ValidIONum(spells[i].target)) { INTERACTIVE_OBJ * io=inter.iobj[spells[i].target]; if (io->ioflags & IO_NPC) { io->_npcdata->poisonned-=cure; if (io->_npcdata->poisonned<0) io->_npcdata->poisonned=0; } ARX_SOUND_PlaySFX(SND_SPELL_CURE_POISON,&io->pos); } } spells[i].exist = TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].tolive = 3500; CSpellFx *pCSpellFx = new CCurePoison(GDevice); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; pCSpellFx->Create(); pCSpellFx->SetDuration(spells[i].tolive); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------- case SPELL_REPEL_UNDEAD: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); long iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_REPEL_UNDEAD,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } ARX_SOUND_PlaySFX(SND_SPELL_REPEL_UNDEAD); if (spells[i].caster==0) spells[i].target=0; if (spells[i].target==0) spells[i].snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_REPEL_UNDEAD_LOOP, &spells[i].caster_pos, 1.0F, ARX_SOUND_PLAY_LOOPED); spells[i].exist = TRUE; spells[i].tolive = 20000000; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 1.f; if (duration>-1) spells[i].tolive=duration; CSpellFx *pCSpellFx = new CRepelUndead(GDevice); if (pCSpellFx != NULL) { EERIE_3D target; target.x=player.pos.x; target.y=player.pos.y; target.z=player.pos.z; pCSpellFx->spellinstance=i; pCSpellFx->Create(target, MAKEANGLE(player.angle.b)); pCSpellFx->SetDuration(spells[i].tolive); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------- case SPELL_POISON_PROJECTILE: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); ARX_SOUND_PlaySFX(SND_SPELL_POISON_PROJECTILE_LAUNCH, &spells[i].caster_pos); spells[i].exist = TRUE; spells[i].tolive = 900000000; CSpellFx *pCSpellFx = NULL; ARX_CHECK_LONG(spells[i].caster_level); pCSpellFx = new CMultiPoisonProjectile( GDevice, __max( ARX_CLEAN_WARN_CAST_LONG( spells[i].caster_level ), 1 ) ); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; EERIE_3D target; Vector_Init(&target); pCSpellFx->SetDuration((unsigned long) (8000)); float ang; if (spells[i].caster==0) ang=player.angle.b; else ang=inter.iobj[spells[i].caster]->angle.b; pCSpellFx->Create(target, MAKEANGLE(ang)); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } SPELLCAST_Notify(i); } break; //*************************************************************************** // LEVEL 6 ----------------------------------------------------------------------------- case SPELL_RISE_DEAD: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); long iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_RISE_DEAD,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } float beta; EERIE_3D target; if (spells[i].caster==0) { target.x=player.pos.x - EEsin(DEG2RAD(MAKEANGLE(player.angle.b)))*300.f; target.y = player.pos.y + 170.f; target.z=player.pos.z + EEcos(DEG2RAD(MAKEANGLE(player.angle.b)))*300.f; beta=MAKEANGLE(player.angle.b); } else { if (inter.iobj[spells[i].caster]->ioflags & IO_NPC) { target.x=inter.iobj[spells[i].caster]->pos.x - EEsin(DEG2RAD(MAKEANGLE(inter.iobj[spells[i].caster]->angle.b)))*300.f; target.y = inter.iobj[spells[i].caster]->pos.y; target.z=inter.iobj[spells[i].caster]->pos.z + EEcos(DEG2RAD(MAKEANGLE(inter.iobj[spells[i].caster]->angle.b)))*300.f; } else { target.x=inter.iobj[spells[i].caster]->pos.x; target.y=inter.iobj[spells[i].caster]->pos.y; target.z=inter.iobj[spells[i].caster]->pos.z; } beta=MAKEANGLE(inter.iobj[spells[i].caster]->angle.b); } if (!ARX_INTERACTIVE_ConvertToValidPosForIO(NULL, &target)) { ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE); return -1; } Vector_Copy(&spells[i].target_pos,&target); ARX_SOUND_PlaySFX(SND_SPELL_RAISE_DEAD, &spells[i].caster_pos); spells[i].exist = TRUE; spells[i].tolive = 2000000; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 1.2f; spells[i].longinfo=-1; if (duration>-1) spells[i].tolive=duration; CSpellFx *pCSpellFx = NULL; pCSpellFx = new CRiseDead(GDevice); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; { pCSpellFx->Create(target, beta); CRiseDead *pRiseDead = (CRiseDead*) pCSpellFx; pRiseDead->SetDuration(2000, 500, 1800); pRiseDead->SetColorBorder(0.5, 0.5, 0.5); pRiseDead->SetColorRays1(0.83f, 0.73f, 0.63f); pRiseDead->SetColorRays2(0,0,0); pRiseDead->SetColorRays1(0.5, 0.5, 0.5); pRiseDead->SetColorRays2(1, 0, 0); if (pRiseDead->lLightId == -1) { pRiseDead->lLightId = GetFreeDynLight(); } if (pRiseDead->lLightId != -1) { long id=pRiseDead->lLightId; DynLight[id].exist=1; DynLight[id].intensity = 1.3f; DynLight[id].fallend=450.f; DynLight[id].fallstart=380.f; DynLight[id].rgb.r=0.0f; DynLight[id].rgb.g=0.0f; DynLight[id].rgb.b=0.0f; DynLight[id].pos.x = target.x; DynLight[id].pos.y = target.y - 100; DynLight[id].pos.z = target.z; DynLight[id].duration=200; DynLight[id].time_creation = ARXTimeUL(); } spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } } SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------- case SPELL_PARALYSE: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); ARX_SOUND_PlaySFX(SND_SPELL_PARALYSE, &spells[i].caster_pos); spells[i].exist = TRUE; spells[i].tolive = 5000; if (duration>-1) spells[i].tolive=duration; if (ValidIONum(spells[i].target)) { if ( (spells[i].target==0) && (spells[i].caster_level<=player.level) ) { float mul=player.resist_magic; if (rnd()*100.fioflags & IO_NPC) { float mul=ioo->_npcdata->resist_magic; if (rnd()*100.fioflags |= IO_FREEZESCRIPT; ARX_SPELLS_AddSpellOn(spells[i].target,i); ARX_NPC_Kill_Spell_Launch(inter.iobj[spells[i].target]); SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------- case SPELL_CREATE_FIELD: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); spells[i].exist = TRUE; if (flags & SPELLCAST_FLAG_RESTORE) { if ((float)ARXTime-4000>0) spells[i].lastupdate = spells[i].timcreation = ARXTimeUL() - 4000; else spells[i].lastupdate = spells[i].timcreation=0; } else spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].tolive = 800000; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 1.2f; if (duration>-1) spells[i].tolive=duration; EERIE_3D target; if (spells[i].caster==0) { target.x = inter.iobj[0]->pos.x - EEsin(DEG2RAD(MAKEANGLE(player.angle.b)))*250.f; target.y = inter.iobj[0]->pos.y; target.z = inter.iobj[0]->pos.z + EEcos(DEG2RAD(MAKEANGLE(player.angle.b)))*250.f; } else { if (ValidIONum(spells[i].caster)) { INTERACTIVE_OBJ * io=inter.iobj[spells[i].caster]; if (io->ioflags & IO_NPC) { target.x = io->pos.x - EEsin(DEG2RAD(MAKEANGLE(io->angle.b)))*250.f; target.y = io->pos.y; target.z = io->pos.z + EEcos(DEG2RAD(MAKEANGLE(io->angle.b)))*250.f; } else { target.x=io->pos.x; target.y=io->pos.y; target.z=io->pos.z; } } } ARX_SOUND_PlaySFX(SND_SPELL_CREATE_FIELD, &target); CSpellFx * pCSpellFx = new CCreateField(GDevice); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; char tmptext[256]; sprintf(tmptext,"%sGraph\\Obj3D\\Interactive\\Fix_inter\\blue_cube\\blue_cube.asl",Project.workingdir); INTERACTIVE_OBJ * io; io=AddFix(GDevice,tmptext,IO_IMMEDIATELOAD); if (io) { ARX_INTERACTIVE_HideGore(io); RestoreInitialIOStatusOfIO(io); spells[i].longinfo=GetInterNum(io); io->scriptload=1; io->ioflags|=IO_NOSAVE; io->ioflags|=IO_FIELD; io->initpos.x=io->pos.x=target.x; io->initpos.y=io->pos.y=target.y; io->initpos.z=io->pos.z=target.z; MakeTemporaryIOIdent(io); SendInitScriptEvent(io); CCreateField *pCreateField = (CCreateField *) pCSpellFx; pCreateField->Create(target, 0); pCreateField->SetDuration(spells[i].tolive); pCreateField->lLightId = GetFreeDynLight(); if (pCreateField->lLightId != -1) { long id=pCreateField->lLightId; DynLight[id].exist=1; DynLight[id].intensity = 0.7f + 2.3f; DynLight[id].fallend = 500.f; DynLight[id].fallstart = 400.f; DynLight[id].rgb.r = 0.8f; DynLight[id].rgb.g = 0.0f; DynLight[id].rgb.b = 1.0f; DynLight[id].pos.x = pCreateField->eSrc.x; DynLight[id].pos.y = pCreateField->eSrc.y-150; DynLight[id].pos.z = pCreateField->eSrc.z; } spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); if (flags & SPELLCAST_FLAG_RESTORE) { pCreateField->Update(4000); } } else spells[i].tolive=0; } SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------- case SPELL_DISARM_TRAP: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); ARX_SOUND_PlaySFX(SND_SPELL_DISARM_TRAP); spells[i].exist = TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].tolive = 1; CSpellFx *pCSpellFx = new CDisarmTrap(GDevice); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; EERIE_3D target; target.x=player.pos.x; target.y=player.pos.y; target.z=player.pos.z; pCSpellFx->Create(target, MAKEANGLE(player.angle.b)); pCSpellFx->SetDuration(spells[i].tolive); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); SPELLCAST_Notify(i); for (long n=0;neSrc.x; sphere.origin.y=crg->eSrc.y; sphere.origin.z=crg->eSrc.z; sphere.radius=400.f; if (EEDistance3D(&target,&sphere.origin)nb_spells_on; il++) { if (spells[io->spells_on[il]].type == SPELL_SLOW_DOWN) { bOk = false; spells[i].exist = false; return -1; } } if (bOk) { ARX_SOUND_PlaySFX(SND_SPELL_SLOW_DOWN, &spells[i].caster_pos); spells[i].exist = TRUE; if (spells[i].caster==0) spells[i].tolive = 10000000; else spells[i].tolive = 10000; if (duration>-1) spells[i].tolive=duration; spells[i].pSpellFx = NULL; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 1.2f; CSpellFx *pCSpellFx = new CSlowDown(GDevice); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; EERIE_3D target; target.x=spells[i].target_pos.x; target.y=spells[i].target_pos.y; target.z=spells[i].target_pos.z; pCSpellFx->Create(target, MAKEANGLE(player.angle.b)); pCSpellFx->SetDuration(spells[i].tolive); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } SPELLCAST_Notify(i); ARX_SPELLS_AddSpellOn(spells[i].target,i); if ((spells[i].target>=0) && (spells[i].targetspeed_modif -= spells[i].caster_level*DIV20; } } } } break; //**************************************************************************************** // LEVEL 7 SPELLS ----------------------------------------------------------------------------- case SPELL_FLYING_EYE: { if (eyeball.exist!=0) return -1; if (ARX_SPELLS_ExistAnyInstanceForThisCaster(typ,spells[i].caster)) return -1; if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); if (spells[i].caster==0) spells[i].target=0; if (spells[i].target!=0) return -1; ARX_SOUND_PlaySFX(SND_SPELL_EYEBALL_IN); spells[i].exist=TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].tolive=1000000; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 3.2f; eyeball.exist=1; eyeball.pos.x=player.pos.x-(float)EEsin(DEG2RAD(MAKEANGLE(player.angle.b)))*200.f; eyeball.pos.y=player.pos.y+50.f; eyeball.pos.z=player.pos.z+(float)EEcos(DEG2RAD(MAKEANGLE(player.angle.b)))*200.f; eyeball.angle.a=player.angle.a; spells[i].v.y=eyeball.angle.b=player.angle.b; eyeball.angle.g=player.angle.g; long j; for (long n=0;n<12;n++) { j=ARX_PARTICLES_GetFree(); if ((j!=-1) && (!ARXPausedTimer)) { ParticleCount++; PARTICLE_DEF * pd=&particle[j]; pd->exist=TRUE; pd->zdec=0; pd->ov.x=eyeball.pos.x+5.f-rnd()*10.f; pd->ov.y=eyeball.pos.y+5.f-rnd()*10.f; pd->ov.z=eyeball.pos.z+5.f-rnd()*10.f; pd->move.x=2.f-4.f*rnd(); pd->move.y=2.f-4.f*rnd(); pd->move.z=2.f-4.f*rnd(); pd->siz=28.f; pd->tolive=2000+(unsigned long)(float)(rnd()*4000.f); pd->scale.x=12.f; pd->scale.y=12.f; pd->scale.z=12.f; pd->timcreation=spells[i].lastupdate; pd->tc=tc4; pd->special=FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING; pd->fparam=0.0000001f; pd->r=0.7f; pd->g=0.7f; pd->b=1.f; } } TRUE_PLAYER_MOUSELOOK_ON |= 1; SLID_START=(float)ARXTime; bOldLookToggle=pMenuConfig->bMouseLookToggle; pMenuConfig->bMouseLookToggle=true; SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------- case SPELL_FIRE_FIELD: { if ( !CanPayMana( i, ARX_SPELLS_GetManaCost( typ, i ) ) ) { return -1; } if ( !GLOBAL_MAGIC_MODE ) { return No_MagicAllowed(); } long iCancel = ARX_SPELLS_GetInstanceForThisCaster( SPELL_FIRE_FIELD, spells[i].caster ); if ( iCancel > -1 ) { spells[iCancel].tolive = 0; } ARX_SOUND_PlaySFX( SND_SPELL_FIRE_FIELD_START ); spells[i].exist = TRUE; spells[i].tolive = 100000; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 2.8f; spells[i].longinfo2 = -1; if ( duration > -1 ) spells[i].tolive = duration; CSpellFx *pCSpellFx = new CFireField(); if ( pCSpellFx != NULL ) { pCSpellFx->spellinstance = i; CFireField *pFireField = (CFireField *)pCSpellFx; EERIE_3D target; if ( spells[i].caster == 0 ) { target.x = player.pos.x - EEsin(DEG2RAD(MAKEANGLE(player.angle.b)))*250.f; target.y = player.pos.y + 170; target.z = player.pos.z + EEcos(DEG2RAD(MAKEANGLE(player.angle.b)))*250.f; } else { if ( ValidIONum( spells[i].caster ) ) { INTERACTIVE_OBJ * io = inter.iobj[spells[i].caster]; if ( io->ioflags & IO_NPC ) { target.x = io->pos.x - EEsin( DEG2RAD( MAKEANGLE( io->angle.b ) ) ) * 250.f; target.y = io->pos.y; target.z = io->pos.z + EEcos( DEG2RAD( MAKEANGLE( io->angle.b ) ) ) * 250.f; } else { target.x = io->pos.x; target.y = io->pos.y; target.z = io->pos.z; } } else { ARX_CHECK_NO_ENTRY(); target.x = 0; target.y = 0; target.z = 0; } } spells[i].longinfo = ARX_DAMAGES_GetFree(); if ( spells[i].longinfo != -1 ) { damages[spells[i].longinfo].radius = 150.f; damages[spells[i].longinfo].damages = 10.f; damages[spells[i].longinfo].area = DAMAGE_FULL; damages[spells[i].longinfo].duration= 100000000; damages[spells[i].longinfo].source = spells[i].caster; damages[spells[i].longinfo].flags = 0; damages[spells[i].longinfo].type = DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_FIRE | DAMAGE_TYPE_FIELD; damages[spells[i].longinfo].exist = TRUE; damages[spells[i].longinfo].pos.x = target.x; damages[spells[i].longinfo].pos.y = target.y; damages[spells[i].longinfo].pos.z = target.z; } pFireField->Create( 200.f, &target, spells[i].tolive ); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pFireField->GetDuration(); spells[i].snd_loop = ARX_SOUND_PlaySFX( SND_SPELL_FIRE_FIELD_LOOP, &target, 1.0F, ARX_SOUND_PLAY_LOOPED ); } SPELLCAST_Notify( i ); } break; //---------------------------------------------------------------------------- case SPELL_ICE_FIELD: { if ( !CanPayMana( i, ARX_SPELLS_GetManaCost( typ, i ) ) ) { return -1; } if ( !GLOBAL_MAGIC_MODE ) { return No_MagicAllowed(); } long iCancel = ARX_SPELLS_GetInstanceForThisCaster( SPELL_ICE_FIELD, spells[i].caster ); if ( iCancel > -1 ) { spells[iCancel].tolive = 0; } ARX_SOUND_PlaySFX(SND_SPELL_ICE_FIELD); spells[i].exist = TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].tolive = 100000; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 2.8f; spells[i].longinfo2 =-1; if ( duration > -1 ) { spells[i].tolive = duration; } CSpellFx *pCSpellFx = new CIceField( GDevice ); if ( pCSpellFx != NULL ) { pCSpellFx->spellinstance = i; EERIE_3D target; if ( spells[i].caster == 0 ) { target.x = player.pos.x - EEsin( DEG2RAD( MAKEANGLE( player.angle.b ) ) ) * 250.f; target.y = player.pos.y + 170; target.z = player.pos.z + EEcos( DEG2RAD( MAKEANGLE( player.angle.b ) ) ) * 250.f; } else { if ( ValidIONum( spells[i].caster ) ) { INTERACTIVE_OBJ * io = inter.iobj[spells[i].caster]; if ( io->ioflags & IO_NPC ) { target.x = io->pos.x - EEsin( DEG2RAD( MAKEANGLE( io->angle.b ) ) ) * 250.f; target.y = io->pos.y; target.z = io->pos.z + EEcos( DEG2RAD( MAKEANGLE( io->angle.b ) ) ) * 250.f; } else { target.x = io->pos.x; target.y = io->pos.y; target.z = io->pos.z; } } else { ARX_CHECK_NO_ENTRY(); target.x = 0; target.y = 0; target.z = 0; } } spells[i].longinfo = ARX_DAMAGES_GetFree(); if ( spells[i].longinfo != -1 ) { damages[spells[i].longinfo].radius = 150.f; damages[spells[i].longinfo].damages = 10.f; damages[spells[i].longinfo].area = DAMAGE_FULL; damages[spells[i].longinfo].duration= 100000000; damages[spells[i].longinfo].source = spells[i].caster; damages[spells[i].longinfo].flags = 0; damages[spells[i].longinfo].type = DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_COLD | DAMAGE_TYPE_FIELD; damages[spells[i].longinfo].exist = TRUE; damages[spells[i].longinfo].pos.x = target.x; damages[spells[i].longinfo].pos.y = target.y; damages[spells[i].longinfo].pos.z = target.z; } pCSpellFx->Create( target, MAKEANGLE( player.angle.b ) ); pCSpellFx->SetDuration( spells[i].tolive ); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } SPELLCAST_Notify( i ); } break; //---------------------------------------------------------------------------- case SPELL_LIGHTNING_STRIKE: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); spells[i].exist = TRUE; CSpellFx *pCSpellFx = new CLightning(); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; CLightning *pL = (CLightning*) pCSpellFx; EERIE_3D source, target; source.x = 0; source.y = 0; source.z = 0; target.x = 0; target.y = 0; target.z = -500; pL->Create(source, target, MAKEANGLE(player.angle.b)); pL->SetDuration((long)(500*spells[i].caster_level)); pL->lSrc = 0; spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } ARX_SOUND_PlaySFX(SND_SPELL_LIGHTNING_START, &spells[i].caster_pos); spells[i].snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_LIGHTNING_LOOP, &spells[i].caster_pos, 1.0F, ARX_SOUND_PLAY_LOOPED); SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------- case SPELL_CONFUSE: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); ARX_SOUND_PlaySFX(SND_SPELL_CONFUSE); spells[i].exist = TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].bDuration = true; spells[i].fManaCostPerSecond = 1.5f; if (duration>-1) spells[i].tolive=duration; CSpellFx *pCSpellFx = new CConfuse(GDevice); if (pCSpellFx) { pCSpellFx->spellinstance=i; EERIE_3D target; target.x=player.pos.x; target.y=player.pos.y; target.z=player.pos.z; pCSpellFx->Create(target, MAKEANGLE(player.angle.b)); pCSpellFx->SetDuration(spells[i].tolive); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } ARX_SPELLS_AddSpellOn(spells[i].target,i); long source = spells[i].caster; char spell[128]; if (MakeSpellName(spell,spells[i].type)) { if (ValidIONum(spells[i].target)) { if (source >= 0) EVENT_SENDER = inter.iobj[source]; else EVENT_SENDER = NULL; char param[256]; sprintf(param,"%s %d",spell,(long)spells[i].caster_level); SendIOScriptEvent(inter.iobj[spells[i].target], SM_SPELLCAST, param); } } } break; //********************************************************************************* // LEVEL 8 SPELLS ----------------------------------------------------------------------------- case SPELL_INVISIBILITY: { if (ARX_SPELLS_ExistAnyInstanceForThisCaster(typ,spells[i].caster)) return -1; if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); spells[i].exist=TRUE; spells[i].tolive=6000000; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 3.f; if (duration>-1) spells[i].tolive=duration; if (spells[i].caster==0) spells[i].target=0; inter.iobj[spells[i].target]->GameFlags|=GFLAG_INVISIBILITY; inter.iobj[spells[i].target]->invisibility=0.f; ARX_SOUND_PlaySFX(SND_SPELL_INVISIBILITY_START, &spells[i].caster_pos); SPELLCAST_Notify(i); ARX_SPELLS_AddSpellOn(spells[i].target,i); } break; //---------------------------------------------------------------------------- case SPELL_MANA_DRAIN: { if (ARX_SPELLS_ExistAnyInstanceForThisCaster(typ,spells[i].caster)) return -1; long iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_LIFE_DRAIN,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_HARM,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); spells[i].exist=TRUE; spells[i].tolive=6000000; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 2.f; spells[i].snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_MAGICAL_SHIELD, &spells[i].caster_pos, 1.2F, ARX_SOUND_PLAY_LOOPED); if (duration>-1) spells[i].tolive=duration; spells[i].longinfo=ARX_DAMAGES_GetFree(); if (spells[i].longinfo!=-1) { damages[spells[i].longinfo].radius=150.f; damages[spells[i].longinfo].damages = 8.f; damages[spells[i].longinfo].area=DAMAGE_FULL; damages[spells[i].longinfo].duration=100000000; damages[spells[i].longinfo].source=spells[i].caster; damages[spells[i].longinfo].flags=DAMAGE_FLAG_DONT_HURT_SOURCE | DAMAGE_FLAG_FOLLOW_SOURCE | DAMAGE_FLAG_ADD_VISUAL_FX; damages[spells[i].longinfo].type=DAMAGE_TYPE_FAKEFIRE | DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_DRAIN_MANA; damages[spells[i].longinfo].exist=TRUE; } spells[i].longinfo2=GetFreeDynLight(); if (spells[i].longinfo2 != -1) { long id = spells[i].longinfo2; DynLight[id].exist = 1; DynLight[id].intensity = 2.3f; DynLight[id].fallend = 700.f; DynLight[id].fallstart = 500.f; DynLight[id].rgb.r = 0.0f; DynLight[id].rgb.g = 0.0f; DynLight[id].rgb.b = 1.0f; DynLight[id].pos.x = spells[i].caster_pos.x; DynLight[id].pos.y = spells[i].caster_pos.y; DynLight[id].pos.z = spells[i].caster_pos.z; DynLight[id].duration=900; } SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------- case SPELL_EXPLOSION: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); ARX_SOUND_PlaySFX(SND_SPELL_EXPLOSION); spells[i].exist = TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].tolive = 2000; spells[i].longinfo=ARX_DAMAGES_GetFree(); EERIE_3D target; target.x=inter.iobj[spells[i].caster]->pos.x; target.y=inter.iobj[spells[i].caster]->pos.y-60.f; if (spells[i].caster==0) target.y+=120.f; target.z=inter.iobj[spells[i].caster]->pos.z; if (spells[i].longinfo!=-1) { damages[spells[i].longinfo].radius=350.f; damages[spells[i].longinfo].damages=10.f; damages[spells[i].longinfo].area = 0; damages[spells[i].longinfo].duration=spells[i].tolive; damages[spells[i].longinfo].source=spells[i].caster; damages[spells[i].longinfo].flags=DAMAGE_FLAG_DONT_HURT_SOURCE | DAMAGE_FLAG_FOLLOW_SOURCE | DAMAGE_FLAG_ADD_VISUAL_FX; damages[spells[i].longinfo].type=DAMAGE_TYPE_FAKEFIRE | DAMAGE_TYPE_MAGICAL; damages[spells[i].longinfo].exist=TRUE; damages[spells[i].longinfo].pos.x=target.x; damages[spells[i].longinfo].pos.y=target.y; damages[spells[i].longinfo].pos.z=target.z; } spells[i].longinfo2=GetFreeDynLight(); if (spells[i].longinfo2 != -1) { long id = spells[i].longinfo2; DynLight[id].exist = 1; DynLight[id].intensity = 2.3f; DynLight[id].fallend = 700.f; DynLight[id].fallstart = 500.f; DynLight[id].rgb.r = 0.1f+rnd()*DIV3; DynLight[id].rgb.g = 0.1f+rnd()*DIV3; DynLight[id].rgb.b = 0.8f+rnd()*DIV5; DynLight[id].pos.x = target.x; DynLight[id].pos.y = target.y; DynLight[id].pos.z = target.z; DynLight[id].duration=200; } AddQuakeFX(300,2000,400,1); for ( long i_angle = 0 ; i_angle < 360 ; i_angle += 12 ) { for ( long j = -100 ; j < 100 ; j += 50 ) { long lvl; float rr, r2; EERIE_3D pos, dir; F2L( ( rnd() * 9.f + 4.f ), &lvl ); rr = DEG2RAD( i_angle ); r2 = DEG2RAD( (float) ( j + 100 ) * DIV200 * 360.f ); pos.x = target.x - EEsin(rr) * 360.f; pos.y = target.y; pos.z = target.z + EEcos(rr) * 360.f; dir.x = pos.x - target.x; dir.y = 0; dir.z = pos.z - target.z; TRUEVector_Normalize( &dir ); dir.x *= 60.f; dir.y *= 60.f; dir.z *= 60.f; EERIE_RGB rgb; rgb.r = 0.1f + rnd() * DIV3; rgb.g = 0.1f + rnd() * DIV3; rgb.b = 0.8f + rnd() * DIV5; EERIE_3D posi; posi.x = target.x; posi.y = target.y + j * 2; posi.z = target.z; LaunchFireballBoom( &posi, 16, &dir, &rgb ); } } ARX_SOUND_PlaySFX(SND_SPELL_FIRE_WIND); SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------- case SPELL_ENCHANT_WEAPON: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); spells[i].exist = TRUE; spells[i].tolive = 20; SPELLCAST_NotifyOnlyTarget(i); } break; //---------------------------------------------------------------------------- case SPELL_LIFE_DRAIN: { if (ARX_SPELLS_ExistAnyInstanceForThisCaster(typ,spells[i].caster)) return -1; if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); long iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_HARM,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } iCancel = ARX_SPELLS_GetInstanceForThisCaster(SPELL_MANA_DRAIN,spells[i].caster); if (iCancel > -1) { spells[iCancel].tolive = 0; } spells[i].exist=TRUE; spells[i].tolive=6000000; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 12.f; if (duration>-1) spells[i].tolive=duration; spells[i].snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_MAGICAL_SHIELD, &spells[i].caster_pos, 0.8F, ARX_SOUND_PLAY_LOOPED); spells[i].longinfo=ARX_DAMAGES_GetFree(); if (spells[i].longinfo!=-1) { long id=spells[i].longinfo; damages[id].radius=150.f; damages[id].damages=spells[i].caster_level*DIV10*.8f; damages[id].area = 0; damages[id].duration=100000000; damages[id].source=spells[i].caster; damages[id].flags=DAMAGE_FLAG_DONT_HURT_SOURCE | DAMAGE_FLAG_FOLLOW_SOURCE | DAMAGE_FLAG_ADD_VISUAL_FX; damages[id].type=DAMAGE_TYPE_FAKEFIRE | DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_DRAIN_LIFE; damages[id].exist=TRUE; } spells[i].longinfo2=GetFreeDynLight(); if (spells[i].longinfo2 != -1) { long id = spells[i].longinfo2; DynLight[id].exist = 1; DynLight[id].intensity = 2.3f; DynLight[id].fallend = 700.f; DynLight[id].fallstart = 500.f; DynLight[id].rgb.r = 1.0f; DynLight[id].rgb.g = 0.0f; DynLight[id].rgb.b = 0.0f; DynLight[id].pos.x = spells[i].caster_pos.x; DynLight[id].pos.y = spells[i].caster_pos.y; DynLight[id].pos.z = spells[i].caster_pos.z; DynLight[id].duration=900; } SPELLCAST_Notify(i); } break; //***************************************************************************************** // LEVEL 9 SPELLS ----------------------------------------------------------------------------- case SPELL_SUMMON_CREATURE: { if (spells[i].caster_level>=9) { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; } else if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); ARX_SOUND_PlaySFX(SND_SPELL_SUMMON_CREATURE); spells[i].exist = TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].bDuration = true; spells[i].fManaCostPerSecond = 1.9f; spells[i].longinfo=0; spells[i].longinfo2=0; if (duration>-1) spells[i].tolive=duration; else spells[i].tolive = 2000000; float beta; EERIE_3D target; if (spells[i].caster==0) { target.x=player.pos.x - EEsin(DEG2RAD(MAKEANGLE(player.angle.b)))*300.f; target.y = player.pos.y + 170.f; target.z=player.pos.z + EEcos(DEG2RAD(MAKEANGLE(player.angle.b)))*300.f; beta=MAKEANGLE(player.angle.b); } else { if (inter.iobj[spells[i].caster]->ioflags & IO_NPC) { target.x=inter.iobj[spells[i].caster]->pos.x - EEsin(DEG2RAD(MAKEANGLE(inter.iobj[spells[i].caster]->angle.b)))*300.f; target.y = inter.iobj[spells[i].caster]->pos.y; target.z=inter.iobj[spells[i].caster]->pos.z + EEcos(DEG2RAD(MAKEANGLE(inter.iobj[spells[i].caster]->angle.b)))*300.f; } else { target.x=inter.iobj[spells[i].caster]->pos.x; target.y=inter.iobj[spells[i].caster]->pos.y; target.z=inter.iobj[spells[i].caster]->pos.z; } beta=MAKEANGLE(inter.iobj[spells[i].caster]->angle.b); } if (!ARX_INTERACTIVE_ConvertToValidPosForIO(NULL, &target)) { spells[i].exist = false; ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE); return -1; } if ((spells[i].caster==0) && (cur_mega==10)) spells[i].fdata=1.f; else spells[i].fdata=0.f; Vector_Copy(&spells[i].target_pos,&target); CSpellFx *pCSpellFx = new CSummonCreature(GDevice); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; CSummonCreature *pSummon = (CSummonCreature*) pCSpellFx; pSummon->Create(target, MAKEANGLE(player.angle.b)); pSummon->SetDuration(2000, 500, 1500); pSummon->SetColorBorder(1, 0, 0); pSummon->SetColorRays1(0.93f, 0.93f, 0.63f); pSummon->SetColorRays2(0,0,0); pSummon->SetColorRays1(1, 0, 0); pSummon->SetColorRays2(0.5f, 0.5f, 0); pCSpellFx->lLightId = GetFreeDynLight(); if (pCSpellFx->lLightId > -1) { long id = pCSpellFx->lLightId; DynLight[id].exist = 1; DynLight[id].intensity = 0.3f; DynLight[id].fallend = 500.f; DynLight[id].fallstart = 400.f; DynLight[id].rgb.r = 1.0f; DynLight[id].rgb.g = 0.0f; DynLight[id].rgb.b = 0.0f; DynLight[id].pos.x = pSummon->eSrc.x; DynLight[id].pos.y = pSummon->eSrc.y; DynLight[id].pos.z = pSummon->eSrc.z; } spells[i].pSpellFx = pCSpellFx; } SPELLCAST_Notify(i); } break; case SPELL_FAKE_SUMMON: { if (spells[i].caster_level>=9) { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; } else if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if ( (spells[i].caster<=0) || (!ValidIONum(spells[i].target)) ) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); ARX_SOUND_PlaySFX(SND_SPELL_SUMMON_CREATURE); spells[i].exist = TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].bDuration = true; spells[i].fManaCostPerSecond = 1.9f; if (duration>-1) spells[i].tolive = 4000; else spells[i].tolive = 4000; EERIE_3D target; target.x=inter.iobj[spells[i].target]->pos.x; target.y=inter.iobj[spells[i].target]->pos.y; target.z=inter.iobj[spells[i].target]->pos.z; if (spells[i].target!=0) target.y-=170.f; Vector_Copy(&spells[i].target_pos,&target); CSpellFx *pCSpellFx = new CSummonCreature(GDevice); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; CSummonCreature *pSummon = (CSummonCreature*) pCSpellFx; pSummon->Create(target, MAKEANGLE(player.angle.b)); pSummon->SetDuration(2000, 500, 1500); pSummon->SetColorBorder(1, 0, 0); pSummon->SetColorRays1(0.93f, 0.93f, 0.63f); pSummon->SetColorRays2(0,0,0); pSummon->SetColorRays1(1, 0, 0); pSummon->SetColorRays2(0.5f, 0.5f, 0); pCSpellFx->lLightId = GetFreeDynLight(); if (pCSpellFx->lLightId > -1) { long id = pCSpellFx->lLightId; DynLight[id].exist = 1; DynLight[id].intensity = 0.3f; DynLight[id].fallend = 500.f; DynLight[id].fallstart = 400.f; DynLight[id].rgb.r = 1.0f; DynLight[id].rgb.g = 0.0f; DynLight[id].rgb.b = 0.0f; DynLight[id].pos.x = pSummon->eSrc.x; DynLight[id].pos.y = pSummon->eSrc.y; DynLight[id].pos.z = pSummon->eSrc.z; } spells[i].pSpellFx = pCSpellFx; } SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------- case SPELL_NEGATE_MAGIC: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); ARX_SOUND_PlaySFX(SND_SPELL_NEGATE_MAGIC); spells[i].exist = TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].bDuration = true; spells[i].fManaCostPerSecond = 2.f; if (duration>-1) spells[i].tolive=duration; else spells[i].tolive = 1000000; CSpellFx *pCSpellFx = new CNegateMagic(GDevice); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; EERIE_3D target; target.x=player.pos.x; target.y=player.pos.y; target.z=player.pos.z; pCSpellFx->Create(target, MAKEANGLE(player.angle.b)); pCSpellFx->SetDuration(spells[i].tolive); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); } if (spells[i].caster==0) spells[i].target=0; if (ValidIONum(spells[i].target)) LaunchAntiMagicField(&inter.iobj[spells[i].target]->pos,i); SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------- case SPELL_INCINERATE: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); INTERACTIVE_OBJ * tio=inter.iobj[spells[i].target]; if ((tio->ioflags & IO_NPC) && (tio->_npcdata->life<=0.f)) return -1; ARX_SOUND_PlaySFX(SND_SPELL_INCINERATE); spells[i].exist = TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].tolive = 20000; tio->sfx_flag|=SFX_TYPE_YLSIDE_DEATH; tio->sfx_flag|=SFX_TYPE_INCINERATE; tio->sfx_time = ARXTimeUL(); ARX_SPELLS_AddSpellOn(spells[i].target,i); SPELLCAST_Notify(i); spells[i].snd_loop = ARX_SOUND_PlaySFX(SND_FIREPLACE, &spells[i].caster_pos, 1.0F, ARX_SOUND_PLAY_LOOPED); } break; //---------------------------------------------------------------------------- case SPELL_MASS_PARALYSE: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); ARX_SOUND_PlaySFX(SND_SPELL_MASS_PARALYSE); spells[i].exist = TRUE; if (duration>-1) spells[i].tolive=duration; else spells[i].tolive = 10000; spells[i].longinfo2=0; for (long ii=0;iiioflags & IO_NPC)) || (tio->show!=SHOW_FLAG_IN_SCENE) || (tio->ioflags & IO_FREEZESCRIPT) || (EEDistance3D(&tio->pos,&inter.iobj[spells[i].caster]->pos)>500.f) ) continue; tio->ioflags |= IO_FREEZESCRIPT; ARX_NPC_Kill_Spell_Launch(tio); ARX_SPELLS_AddSpellOn(ii,i); spells[i].longinfo2++; spells[i].misc=realloc(spells[i].misc,sizeof(long)*spells[i].longinfo2); long * ptr=(long *)spells[i].misc; ptr[spells[i].longinfo2-1]=ii; } SPELLCAST_Notify(i); } break; //******************************************************************************************** // LEVEL 10 SPELLS ----------------------------------------------------------------------------- case SPELL_MASS_LIGHTNING_STRIKE: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); for (long ii=0;iispellinstance=i; EERIE_3D target; float beta; if (spells[i].caster==0) { target.x=player.pos.x - EEsin(DEG2RAD(MAKEANGLE(player.angle.b)))*500.f; target.y=player.pos.y + 150.f; target.z=player.pos.z + EEcos(DEG2RAD(MAKEANGLE(player.angle.b)))*500.f; beta=player.angle.b; } else { INTERACTIVE_OBJ * io=inter.iobj[spells[i].caster]; target.x=io->pos.x - EEsin(DEG2RAD(MAKEANGLE(io->angle.b)))*500.f; target.y=io->pos.y - 20.f; target.z=io->pos.z + EEcos(DEG2RAD(MAKEANGLE(io->angle.b)))*500.f; beta=io->angle.b; } pCSpellFx->SetDuration((long)(500*spells[i].caster_level)); pCSpellFx->Create(target, MAKEANGLE(player.angle.b)); spells[i].pSpellFx = pCSpellFx; spells[i].tolive = pCSpellFx->GetDuration(); spells[i].snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_LIGHTNING_LOOP, &target, 1.0F, ARX_SOUND_PLAY_LOOPED); } ARX_SOUND_PlaySFX(SND_SPELL_LIGHTNING_START); SPELLCAST_Notify(i); // Draws White Flash on Screen GDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); GDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE); SETALPHABLEND(GDevice,TRUE); float val = 1.f; EERIEDrawBitmap(GDevice,0.f,0.f,(float)DANAESIZX,(float)DANAESIZY,0.00009f,NULL,D3DRGB(0.5f+val*DIV2,val,val)); SETALPHABLEND(GDevice,FALSE); } break; //---------------------------------------------------------------------------- case SPELL_CONTROL_TARGET: { if (ARX_SPELLS_ExistAnyInstanceForThisCaster(typ,spells[i].caster)) return -1; if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!ValidIONum(spells[i].target)) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); long tcount=0; INTERACTIVE_OBJ * tmp_io=inter.iobj[spells[i].target]; for (long ii=1;iiioflags & IO_NPC) && (ioo->_npcdata->life>0.f) && (ioo->show==SHOW_FLAG_IN_SCENE) && (IsIOGroup(ioo,"DEMON")) && (EEDistance3D(&ioo->pos,&spells[i].caster_pos)<900.f) ) { tcount++; char param[256]; long n; F2L(spells[i].caster_level,&n); sprintf(param,"%s_%04d %d" ,GetName(tmp_io->filename) ,tmp_io->ident ,n ); SendIOScriptEvent(ioo,-1,param,"NPC_CONTROL"); } } if (tcount==0) return -1; ARX_SOUND_PlaySFX(SND_SPELL_CONTROL_TARGET); spells[i].exist = TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].tolive = 1000; CSpellFx *pCSpellFx = NULL; pCSpellFx = new CControlTarget(GDevice); if (pCSpellFx != NULL) { pCSpellFx->spellinstance=i; EERIE_3D target; target.x=player.pos.x; target.y=player.pos.y; target.z=player.pos.z; pCSpellFx->Create(target, MAKEANGLE(player.angle.b)); pCSpellFx->SetDuration(spells[i].tolive); spells[i].pSpellFx = pCSpellFx; } SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------- case SPELL_FREEZE_TIME: { if (ARX_SPELLS_ExistAnyInstanceForThisCaster(typ,spells[i].caster)) return -1; if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); ARX_SOUND_PlaySFX(SND_SPELL_FREEZETIME); //ARX_TIME_Pause(); spells[i].siz=spells[i].caster_level*0.08f; GLOBAL_SLOWDOWN -= spells[i].siz; spells[i].exist=TRUE; spells[i].tolive=200000; if (duration>-1) spells[i].tolive=duration; spells[i].bDuration = true; spells[i].fManaCostPerSecond = 30.f*spells[i].siz; spells[i].longinfo=(long)ARX_TIME_Get(); SPELLCAST_Notify(i); } break; //---------------------------------------------------------------------------- case SPELL_MASS_INCINERATE: { if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); ARX_SOUND_PlaySFX(SND_SPELL_MASS_INCINERATE); spells[i].exist = TRUE; spells[i].lastupdate = spells[i].timcreation = ARXTimeUL(); spells[i].tolive = 20000; long nb_targets=0; for (long ii=0;iiioflags & IO_NPC)) || ((tio->ioflags & IO_NPC) && (tio->_npcdata->life<=0.f)) || (tio->show!=SHOW_FLAG_IN_SCENE) || (EEDistance3D(&tio->pos,&inter.iobj[spells[i].caster]->pos)>500.f) ) continue; tio->sfx_flag|=SFX_TYPE_YLSIDE_DEATH; tio->sfx_flag|=SFX_TYPE_INCINERATE; tio->sfx_time = ARXTimeUL(); nb_targets++; ARX_SPELLS_AddSpellOn(ii,i); } SPELLCAST_Notify(i); if (nb_targets) spells[i].snd_loop = ARX_SOUND_PlaySFX(SND_FIREPLACE, &spells[i].caster_pos, 1.0F, ARX_SOUND_PLAY_LOOPED); else spells[i].snd_loop = -1; } break; //---------------------------------------------------------------------------- case SPELL_TELEPORT: { if (ARX_SPELLS_ExistAnyInstanceForThisCaster(typ,spells[i].caster)) return -1; if (!CanPayMana(i,ARX_SPELLS_GetManaCost(typ,i))) return -1; if (!GLOBAL_MAGIC_MODE) return No_MagicAllowed(); spells[i].exist=TRUE; spells[i].tolive=7000; ARX_SOUND_PlaySFX(SND_SPELL_TELEPORT, &spells[i].caster_pos); if (spells[i].caster==0) LASTTELEPORT = 0.0F; SPELLCAST_Notify(i); } break; } return i; } //************************************************************************************* // Used for specific Spell-End FX //************************************************************************************* void ARX_SPELLS_Kill(const long &i) { static TextureContainer * tc4=MakeTCFromFile("Graph\\Particles\\smoke.bmp"); if (!spells[i].exist) return; spells[i].exist=FALSE; // All Levels - Kill Light if (spells[i].pSpellFx && spells[i].pSpellFx->lLightId != -1) { DynLight[spells[i].pSpellFx->lLightId].duration = 500; DynLight[spells[i].pSpellFx->lLightId].time_creation = ARXTimeUL(); } switch(spells[i].type) { //---------------------------------------------------------------------------- case SPELL_FIREBALL : if (spells[i].longinfo!=-1) { DynLight[spells[i].longinfo].duration = 500; DynLight[spells[i].longinfo].time_creation = ARXTimeUL(); } spells[i].longinfo=-1; if (spells[i].pSpellFx) delete spells[i].pSpellFx; spells[i].pSpellFx=NULL; break; //---------------------------------------------------------------------------- case SPELL_LIGHTNING_STRIKE : if (spells[i].longinfo!=-1) { DynLight[spells[i].longinfo].duration = 200; DynLight[spells[i].longinfo].time_creation = ARXTimeUL(); } spells[i].longinfo=-1; ARX_SOUND_Stop(spells[i].snd_loop); ARX_SOUND_PlaySFX(SND_SPELL_LIGHTNING_END); if (spells[i].pSpellFx) delete spells[i].pSpellFx; spells[i].pSpellFx=NULL; break; //---------------------------------------------------------------------------- case SPELL_MASS_LIGHTNING_STRIKE : if (spells[i].longinfo!=-1) { DynLight[spells[i].longinfo].duration = 200; DynLight[spells[i].longinfo].time_creation = ARXTimeUL(); } spells[i].longinfo=-1; ARX_SOUND_Stop(spells[i].snd_loop); ARX_SOUND_PlaySFX(SND_SPELL_LIGHTNING_END); if (spells[i].pSpellFx) delete spells[i].pSpellFx; spells[i].pSpellFx=NULL; break; case SPELL_REPEL_UNDEAD: if (spells[i].longinfo!=-1) { DynLight[spells[i].longinfo].duration = 200; DynLight[spells[i].longinfo].time_creation = ARXTimeUL(); } spells[i].longinfo=-1; ARX_SOUND_Stop(spells[i].snd_loop); if (spells[i].pSpellFx) delete spells[i].pSpellFx; spells[i].pSpellFx=NULL; break; //---------------------------------------------------------------------------- case SPELL_HARM : case SPELL_LIFE_DRAIN : case SPELL_MANA_DRAIN : if (spells[i].longinfo!=-1) damages[spells[i].longinfo].exist=FALSE; if (spells[i].longinfo2!=-1) { DynLight[spells[i].longinfo2].time_creation = ARXTimeUL(); DynLight[spells[i].longinfo2].duration = 600; } ARX_SOUND_Stop(spells[i].snd_loop); break; //---------------------------------------------------------------------------- case SPELL_FLYING_EYE : { ARX_SOUND_PlaySFX(SND_SPELL_EYEBALL_OUT); eyeball.exist = -100; for (long n=0;n<12;n++) { long j = ARX_PARTICLES_GetFree(); if ((j!=-1) && (!ARXPausedTimer)) { ParticleCount++; PARTICLE_DEF * pd=&particle[j]; pd->exist=TRUE; pd->zdec=0; pd->ov.x=eyeball.pos.x+5.f-rnd()*10.f; pd->ov.y=eyeball.pos.y+5.f-rnd()*10.f; pd->ov.z=eyeball.pos.z+5.f-rnd()*10.f; pd->move.x=2.f-4.f*rnd(); pd->move.y=2.f-4.f*rnd(); pd->move.z=2.f-4.f*rnd(); pd->siz=28.f; pd->tolive=2000+(unsigned long)(float)(rnd()*4000.f); Vector_Init(&pd->scale,12.f,12.f,12.f); pd->timcreation=spells[i].lastupdate; pd->tc=tc4; pd->special=FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING; pd->fparam=0.0000001f; pd->r=0.7f; pd->g=0.7f; pd->b=1.f; } } pMenuConfig->bMouseLookToggle = bOldLookToggle; break; } //---------------------------------------------------------------------------- // Level 06 //---------------------------------------LEVEL1 case SPELL_IGNIT: if (spells[i].pSpellFx) delete spells[i].pSpellFx; spells[i].pSpellFx=NULL; break; case SPELL_DOUSE: if (spells[i].pSpellFx) delete spells[i].pSpellFx; spells[i].pSpellFx=NULL; break; //---------------------------------------------------------------------------- case SPELL_PARALYSE: ARX_SOUND_PlaySFX(SND_SPELL_PARALYSE_END); break; //--------------------------------------------------------------------- // Level 7 case SPELL_FIRE_FIELD: { ARX_SOUND_Stop(spells[i].snd_loop); ARX_SOUND_PlaySFX(SND_SPELL_FIRE_FIELD_END); } break; case SPELL_LOWER_ARMOR: break; //---------------------------------------------------------------------------- case SPELL_EXPLOSION: { if (spells[i].pSpellFx) delete spells[i].pSpellFx; spells[i].pSpellFx=NULL; break; } //---------------------------------------------------------------------------- case SPELL_MASS_PARALYSE: ARX_SOUND_PlaySFX(SND_SPELL_PARALYSE_END); break; //---------------------------------------------------------------------------- case SPELL_SUMMON_CREATURE: if (spells[i].pSpellFx->lLightId > -1) { long id = spells[i].pSpellFx->lLightId; DynLight[id].exist = 0; spells[i].pSpellFx->lLightId=-1; } if (ValidIONum(spells[i].longinfo2) && (spells[i].longinfo2!=0)) { if ( (inter.iobj[spells[i].longinfo2]->scriptload) && (inter.iobj[spells[i].longinfo2]->ioflags & IO_NOSAVE) ) { AddRandomSmoke(inter.iobj[spells[i].longinfo2],100); EERIE_3D posi; Vector_Copy(&posi,&inter.iobj[spells[i].longinfo2]->pos); posi.y-=100.f; MakeCoolFx(&posi); long nn=GetFreeDynLight(); if (nn>=0) { DynLight[nn].exist=1; DynLight[nn].intensity = 0.7f + 2.f*rnd(); DynLight[nn].fallend = 600.f; DynLight[nn].fallstart = 400.f; DynLight[nn].rgb.r = 1.0f; DynLight[nn].rgb.g = 0.8f; DynLight[nn].rgb.b = .0f; DynLight[nn].pos.x = posi.x; DynLight[nn].pos.y = posi.y; DynLight[nn].pos.z = posi.z; DynLight[nn].duration=600; } ARX_INTERACTIVE_DestroyIO(inter.iobj[spells[i].longinfo2]); } } spells[i].longinfo2=0; break; case SPELL_FAKE_SUMMON: if (spells[i].pSpellFx->lLightId > -1) { long id = spells[i].pSpellFx->lLightId; DynLight[id].exist = 0; spells[i].pSpellFx->lLightId=-1; } break; default: if (spells[i].pSpellFx) delete spells[i].pSpellFx; spells[i].pSpellFx=NULL; break; } if (spells[i].pSpellFx) delete spells[i].pSpellFx; spells[i].pSpellFx=NULL; } EYEBALL_DEF eyeball; EERIE_3D cabalangle; EERIE_3D cabalpos; EERIE_3D cabalscale; EERIE_RGB cabalcolor; float ARX_SPELLS_ApplyFireProtection(INTERACTIVE_OBJ * io,float damages) { if (io) { long idx=ARX_SPELLS_GetSpellOn(io,SPELL_FIRE_PROTECTION); if (idx>=0) { float modif=1.f-((float)spells[idx].caster_level*DIV10); if (modif>1.f) modif=1.f; else if (modif<0.f) modif=0.f; damages*=modif; } if (io->ioflags & IO_NPC) { damages-=io->_npcdata->resist_fire*DIV100*damages; if (damages<0.f) damages=0.f; } } return damages; } float ARX_SPELLS_ApplyColdProtection(INTERACTIVE_OBJ * io,float damages) { long idx=ARX_SPELLS_GetSpellOn(io,SPELL_COLD_PROTECTION); if (idx>=0) { float modif=1.f-((float)spells[idx].caster_level*DIV10); if (modif>1.f) modif=1.f; else if (modif<0.f) modif=0.f; damages*=modif; } return damages; } //************************************************************************************* // Updates all currently working spells. //************************************************************************************* extern bool bSoftRender; void ARX_SPELLS_Update(LPDIRECT3DDEVICE7 m_pd3dDevice) { bool bNoVB = false; if( bSoftRender ) { bNoVB = GET_FORCE_NO_VB(); SET_FORCE_NO_VB( true ); } register long i; register unsigned long tim; register long framediff,framediff2,framediff3; ucFlick++; tim = ARXTimeUL(); for (i=0;iAction(1); } break; //---------------------------------------------------------------------------- case SPELL_DOUSE: { CDoze *pDoze; pDoze=(CDoze *)spells[i].pSpellFx; pDoze->Action(0); } break; //---------------------------------------------------------------------------------- //********************************************************************************** // LEVEL 2 ------------------------------------------------------------------------- //---------------------------------------------------------------------------------- case SPELL_DETECT_TRAP: if (spells[i].caster==0) { Project.improve=0; ARX_SOUND_Stop(spells[i].snd_loop); } break; //---------------------------------------------------------------------------- case SPELL_ARMOR: { ARX_SOUND_Stop(spells[i].snd_loop); ARX_SOUND_PlaySFX(SND_SPELL_ARMOR_END, &spells[i].caster_pos); INTERACTIVE_OBJ * io=inter.iobj[spells[i].target]; if (spells[i].longinfo) { io->halo.flags&=~HALO_ACTIVE; ARX_HALO_SetToNative(io); } ARX_SPELLS_RemoveSpellOn(spells[i].target,i); } break; //---------------------------------------------------------------------------- case SPELL_LOWER_ARMOR: { INTERACTIVE_OBJ * io=inter.iobj[spells[i].target]; if (spells[i].longinfo) { io->halo.flags&=~HALO_ACTIVE; ARX_HALO_SetToNative(io); } ARX_SPELLS_RemoveSpellOn(spells[i].target,i); } break; //---------------------------------------------------------------------------------- //********************************************************************************** // LEVEL 3 ------------------------------------------------------------------------- //---------------------------------------------------------------------------------- case SPELL_SPEED: ARX_SPELLS_RemoveSpellOn(spells[i].target,i); if ((spells[i].target>=0) && (spells[i].targetspeed_modif-=spells[i].caster_level*DIV10; } if (spells[i].caster == 0) ARX_SOUND_Stop(spells[i].snd_loop); ARX_SOUND_PlaySFX(SND_SPELL_INVISIBILITY_END, &spells[i].caster_pos); break; //---------------------------------------------------------------------------------- case SPELL_FIREBALL: ARX_SOUND_Stop(spells[i].snd_loop); break; //---------------------------------------------------------------------------------- //********************************************************************************** // LEVEL 4 ------------------------------------------------------------------------- //---------------------------------------------------------------------------------- case SPELL_BLESS: ARX_SPELLS_RemoveSpellOn(spells[i].target,i); break; case SPELL_CURSE: ARX_SPELLS_RemoveSpellOn(spells[i].target,i); break; //---------------------------------------------------------------------------- case SPELL_TELEKINESIS: if (spells[i].caster==0) Project.telekinesis=0; ARX_SOUND_PlaySFX(SND_SPELL_TELEKINESIS_END, &spells[i].caster_pos); break; case SPELL_FIRE_PROTECTION: ARX_SPELLS_RemoveSpellOn(spells[i].target,i);; if (ValidIONum(spells[i].target)) ARX_HALO_SetToNative(inter.iobj[spells[i].target]); break; case SPELL_COLD_PROTECTION: ARX_SOUND_Stop(spells[i].snd_loop); ARX_SOUND_PlaySFX(SND_SPELL_COLD_PROTECTION_END); ARX_SPELLS_RemoveSpellOn(spells[i].target,i);; if (ValidIONum(spells[i].target)) ARX_HALO_SetToNative(inter.iobj[spells[i].target]); break; //---------------------------------------------------------------------------------- //********************************************************************************** // LEVEL 5 ------------------------------------------------------------------------- //---------------------------------------------------------------------------------- //---------------------------------------------------------------------------- case SPELL_LEVITATE: { ARX_SPELLS_RemoveSpellOn(spells[i].target,i); if (spells[i].target==0) player.levitate=0; } break; //---------------------------------------------------------------------------------- //********************************************************************************** // LEVEL 6 SPELLS ------------------------------------------------------------------ //---------------------------------------------------------------------------------- case SPELL_PARALYSE: ARX_SPELLS_RemoveSpellOn(spells[i].target,i); inter.iobj[spells[i].target]->ioflags&=~IO_FREEZESCRIPT; break; //---------------------------------------------------------------------------------- case SPELL_RISE_DEAD: ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, &spells[i].caster_pos); if (ValidIONum(spells[i].longinfo) && spells[i].longinfo!=0) { if ( (inter.iobj[spells[i].longinfo]->scriptload) && (inter.iobj[spells[i].longinfo]->ioflags & IO_NOSAVE) ) { AddRandomSmoke(inter.iobj[spells[i].longinfo],100); EERIE_3D posi; Vector_Copy(&posi,&inter.iobj[spells[i].longinfo]->pos); posi.y-=100.f; MakeCoolFx(&posi); long nn=GetFreeDynLight(); if (nn>=0) { DynLight[nn].exist=1; DynLight[nn].intensity = 0.7f + 2.f*rnd(); DynLight[nn].fallend = 600.f; DynLight[nn].fallstart = 400.f; DynLight[nn].rgb.r = 1.0f; DynLight[nn].rgb.g = 0.8f; DynLight[nn].rgb.b = .0f; DynLight[nn].pos.x = posi.x; DynLight[nn].pos.y = posi.y; DynLight[nn].pos.z = posi.z; DynLight[nn].duration=600; } ARX_INTERACTIVE_DestroyIO(inter.iobj[spells[i].longinfo]); } } break; case SPELL_CREATE_FIELD: CCreateField * pCreateField; pCreateField = (CCreateField *) spells[i].pSpellFx; if ( (pCreateField) && (pCreateField->lLightId != -1) ) { long id=pCreateField->lLightId; DynLight[id].duration=800; } if (ValidIONum(spells[i].longinfo)) { ReleaseInter(inter.iobj[spells[i].longinfo]); } break; //---------------------------------------------------------------------------- case SPELL_SLOW_DOWN: ARX_SPELLS_RemoveSpellOn(spells[i].target,i); if ((spells[i].target>=0) && (spells[i].targetspeed_modif+=spells[i].caster_level*DIV20; } break; //---------------------------------------------------------------------------------- //********************************************************************************** // LEVEL 7 ------------------------------------------------------------------------- //---------------------------------------------------------------------------------- case SPELL_ICE_FIELD: if (spells[i].longinfo!=-1) damages[spells[i].longinfo].exist=FALSE; break; case SPELL_FIRE_FIELD: if (spells[i].longinfo!=-1) damages[spells[i].longinfo].exist=FALSE; break; //---------------------------------------------------------------------------- case SPELL_LIGHTNING_STRIKE: ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, &spells[i].caster_pos); break; //---------------------------------------------------------------------------- case SPELL_FLYING_EYE: ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE, &inter.iobj[spells[i].caster]->pos); break; case SPELL_CONFUSE: ARX_SPELLS_RemoveSpellOn(spells[i].target,i); break; //---------------------------------------------------------------------------------- //********************************************************************************** // LEVEL 8 ------------------------------------------------------------------------- //---------------------------------------------------------------------------------- case SPELL_EXPLOSION: break; //---------------------------------------------------------------------------- case SPELL_INVISIBILITY: inter.iobj[spells[i].target]->GameFlags&=~GFLAG_INVISIBILITY; ARX_SOUND_PlaySFX(SND_SPELL_INVISIBILITY_END, &inter.iobj[spells[i].target]->pos); ARX_SPELLS_RemoveSpellOn(spells[i].target,i); break; //---------------------------------------------------------------------------------- //********************************************************************************** // LEVEL 9 ------------------------------------------------------------------------- //---------------------------------------------------------------------------------- //---------------------------------------------------------------------------- case SPELL_MASS_PARALYSE: { long * ptr=(long *)spells[i].misc; for (long in=0;inioflags&=~IO_FREEZESCRIPT; } } if (ptr) free(spells[i].misc); spells[i].misc=NULL; } break; case SPELL_SUMMON_CREATURE : ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, &spells[i].caster_pos); if (spells[i].pSpellFx->lLightId > -1) { long id = spells[i].pSpellFx->lLightId; DynLight[id].exist = 0; spells[i].pSpellFx->lLightId=-1; } // need to killio break; case SPELL_FAKE_SUMMON : ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, &spells[i].caster_pos); if (spells[i].pSpellFx->lLightId > -1) { long id = spells[i].pSpellFx->lLightId; DynLight[id].exist = 0; spells[i].pSpellFx->lLightId=-1; } break; case SPELL_INCINERATE: ARX_SPELLS_RemoveSpellOn(spells[i].target,i); ARX_SOUND_Stop(spells[i].snd_loop); break; //---------------------------------------------------------------------------------- //********************************************************************************** // LEVEL 10 ------------------------------------------------------------------------ //---------------------------------------------------------------------------------- case SPELL_FREEZE_TIME: GLOBAL_SLOWDOWN += spells[i].siz; ARX_SOUND_PlaySFX(SND_SPELL_TELEKINESIS_END, &spells[i].caster_pos); break; case SPELL_MASS_INCINERATE: ARX_SPELLS_RemoveMultiSpellOn(i); ARX_SOUND_Stop(spells[i].snd_loop); break; //---------------------------------------------------------------------------------- } ARX_SPELLS_Kill(i); continue; } //****************************************************************************************** //****************************************************************************************** //****************************************************************************************** //****************************************************************************************** //****************************************************************************************** //****************************************************************************************** if (spells[i].exist) switch (spells[i].type) { //************************************************************************************** // LEVEL 1 ----------------------------------------------------------------------------- case SPELL_MAGIC_MISSILE: { CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { CMultiMagicMissile *pMMM = (CMultiMagicMissile *) pCSpellFX; pMMM->CheckCollision(1.f); // Update pCSpellFX->Update(FrameDiff); if (pCSpellFX->Render(m_pd3dDevice)==-1) spells[i].tolive=0; } } break; //--------------------------------------------------------------------------------------- case SPELL_IGNIT: case SPELL_DOUSE: { CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { pCSpellFX->Update(FrameDiff); } } break; //--------------------------------------------------------------------------------------- case SPELL_ACTIVATE_PORTAL: { } break; //--------------------------------------------------------------------------------------- //*************************************************************************************** // LEVEL 2 ----------------------------------------------------------------------------- case SPELL_HEAL: // guérit les ennemis collés { CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { pCSpellFX->Update(FrameDiff); pCSpellFX->Render(m_pd3dDevice); } CHeal * ch=(CHeal *)pCSpellFX; if (ch) for (long ii=0;iishow==SHOW_FLAG_IN_SCENE) && (inter.iobj[ii]->GameFlags & GFLAG_ISINTREATZONE) && (inter.iobj[ii]->ioflags & IO_NPC) && (inter.iobj[ii]->_npcdata->life>0.f) ) { float dist; if (ii==spells[i].caster) dist=0; else dist=EEDistance3D(&ch->eSrc,&inter.iobj[ii]->pos); if (dist<300.f) { float gain=((rnd()*1.6f+0.8f)*spells[i].caster_level)*(300.f-dist)*DIV300*_framedelay*DIV1000; if (ii==0) { if (!BLOCK_PLAYER_CONTROLS) player.life=min(player.life+gain,player.Full_maxlife); } else inter.iobj[ii]->_npcdata->life=min(inter.iobj[ii]->_npcdata->life+gain,inter.iobj[ii]->_npcdata->maxlife); } } } } break; //------------------------------------------------------------------------------------ case SPELL_DETECT_TRAP: { if (spells[i].caster == 0) { ARX_SOUND_RefreshPosition(spells[i].snd_loop); } CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { pCSpellFX->Update(FrameDiff); pCSpellFX->Render(m_pd3dDevice); } } break; //------------------------------------------------------------------------------------ case SPELL_ARMOR: case SPELL_LOWER_ARMOR: { CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { pCSpellFX->Update(FrameDiff); pCSpellFX->Render(m_pd3dDevice); } } break; //-------------------------------------------------------------------------------------- case SPELL_HARM: { if ( (cabal!=NULL) ) { float refpos; float scaley; if (spells[i].caster==0) scaley=90.f; else scaley=EEfabs(inter.iobj[spells[i].caster]->physics.cyl.height*DIV2)+30.f; float mov=EEsin((float)FrameTime*DIV800)*scaley; if (spells[i].caster==0) { cabalpos.x = player.pos.x; cabalpos.y=player.pos.y+60.f-mov; cabalpos.z = player.pos.z; refpos=player.pos.y+60.f; } else { cabalpos.x = inter.iobj[spells[i].caster]->pos.x; cabalpos.y=inter.iobj[spells[i].caster]->pos.y-scaley-mov; cabalpos.z = inter.iobj[spells[i].caster]->pos.z; refpos=inter.iobj[spells[i].caster]->pos.y-scaley; } float Es=EEsin((float)FrameTime*DIV800 + DEG2RAD(scaley)); if (spells[i].longinfo2!=-1) { DynLight[spells[i].longinfo2].pos.x = cabalpos.x; DynLight[spells[i].longinfo2].pos.y = refpos; DynLight[spells[i].longinfo2].pos.z = cabalpos.z; DynLight[spells[i].longinfo2].rgb.r=rnd()*0.2f+0.8f; DynLight[spells[i].longinfo2].rgb.g=rnd()*0.2f+0.6f; DynLight[spells[i].longinfo2].fallstart=Es*1.5f; } GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE ); SETALPHABLEND(GDevice,TRUE); SETZWRITE(GDevice, FALSE ); cabalangle.b=spells[i].fdata+(float)FrameDiff*0.1f; spells[i].fdata=cabalangle.b; cabalangle.g = 0.f; cabalcolor.r = 0.8f; cabalcolor.g = 0.4f; cabalcolor.b = 0.f; cabalscale.z=cabalscale.y=cabalscale.x=Es; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); mov=EEsin((float)(FrameTime-30.f)*DIV800)*scaley; cabalpos.y=refpos-mov; cabalcolor.b = 0.f; cabalcolor.g = 3.f; cabalcolor.r = 0.5f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); mov=EEsin((float)(FrameTime-60.f)*DIV800)*scaley; cabalpos.y=refpos-mov; cabalcolor.b = 0.f; cabalcolor.g = 0.1f; cabalcolor.r = 0.25f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); mov=EEsin((float)(FrameTime-120.f)*DIV800)*scaley; cabalpos.y=refpos-mov; cabalcolor.b = 0.f; cabalcolor.g = 0.1f; cabalcolor.r = 0.15f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); SETALPHABLEND(GDevice,FALSE); SETZWRITE(GDevice, TRUE ); } } break; //-------------------------------------------------------------------------------------- //************************************************************************************** // LEVEL 3 SPELLS ----------------------------------------------------------------------------- case SPELL_FIREBALL: { CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { CFireBall *pCF = (CFireBall*) pCSpellFX; if (spells[i].longinfo==-1) spells[i].longinfo=GetFreeDynLight(); if (spells[i].longinfo!=-1) { long id=spells[i].longinfo; EERIE_LIGHT * el=&DynLight[id]; el->exist=1; Vector_Copy(&el->pos,&pCF->eCurPos); el->intensity = 2.2f; el->fallend = 500.f; el->fallstart = 400.f; el->rgb.r = 1.0f-rnd()*0.3f; el->rgb.g = 0.6f-rnd()*0.1f;; el->rgb.b = 0.3f-rnd()*0.1f;; } EERIE_SPHERE sphere; sphere.origin.x=pCF->eCurPos.x; sphere.origin.y=pCF->eCurPos.y; sphere.origin.z=pCF->eCurPos.z; sphere.radius=__max(spells[i].caster_level*2.f,12.f); #define MIN_TIME_FIREBALL 2000 if (pCF->pPSFire.iParticleNbMax) { if (pCF->ulCurrentTime > MIN_TIME_FIREBALL) { SpawnFireballTail(&pCF->eCurPos,&pCF->eMove,(float)spells[i].caster_level,0); } else { if (rnd()<0.9f) { EERIE_3D move; Vector_Init(&move); float dd=(float)pCF->ulCurrentTime / (float)MIN_TIME_FIREBALL*10; if (dd>spells[i].caster_level) dd=spells[i].caster_level; if (dd<1) dd=1; SpawnFireballTail(&pCF->eCurPos,&move,(float)dd,1); } } } if (pCF->bExplo == false) if (CheckAnythingInSphere(&sphere,spells[i].caster,CAS_NO_SAME_GROUP)) { ARX_BOOMS_Add(&pCF->eCurPos); LaunchFireballBoom(&pCF->eCurPos,(float)spells[i].caster_level); pCF->pPSFire.iParticleNbMax = 0; pCF->pPSFire2.iParticleNbMax = 0; pCF->eMove.x *= 0.5f; pCF->eMove.y *= 0.5f; pCF->eMove.z *= 0.5f; pCF->pPSSmoke.iParticleNbMax = 0; pCF->SetTTL(1500); pCF->bExplo = true; DoSphericDamage(&pCF->eCurPos,3.f*spells[i].caster_level,30.f*spells[i].caster_level,DAMAGE_AREA,DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL,spells[i].caster); spells[i].tolive=0; ARX_SOUND_PlaySFX(SND_SPELL_FIRE_HIT, &sphere.origin); ARX_NPC_SpawnAudibleSound(&sphere.origin, inter.iobj[spells[i].caster]); } pCSpellFX->Update(FrameDiff); ARX_SOUND_RefreshPosition(spells[i].snd_loop, &pCF->eCurPos); } } break; //----------------------------------------------------------------------------------------- case SPELL_SPEED: if (spells[i].pSpellFx) { spells[i].pSpellFx->Update(FrameDiff); spells[i].pSpellFx->Render(m_pd3dDevice); if (spells[i].caster == 0) ARX_SOUND_RefreshPosition(spells[i].snd_loop); } break; //----------------------------------------------------------------------------------------- case SPELL_CREATE_FOOD: case SPELL_ICE_PROJECTILE: case SPELL_DISPELL_ILLUSION: if (spells[i].pSpellFx) { spells[i].pSpellFx->Update(FrameDiff); spells[i].pSpellFx->Render(m_pd3dDevice); } break; //----------------------------------------------------------------------------------------- //***************************************************************************************** // LEVEL 4 SPELLS ----------------------------------------------------------------------------- case SPELL_BLESS: { if (spells[i].pSpellFx) { CBless * pBless=(CBless *)spells[i].pSpellFx; if (pBless) { if (ValidIONum(spells[i].target)) { Vector_Copy(&pBless->eSrc,&inter.iobj[spells[i].target]->pos); EERIE_3D angle; Vector_Init(&angle); if (spells[i].target==0) angle.b=player.angle.b; else angle.b=inter.iobj[spells[i].target]->angle.b; pBless->Set_Angle(angle); } } spells[i].pSpellFx->Update(FrameDiff); spells[i].pSpellFx->Render(m_pd3dDevice); } } break; //----------------------------------------------------------------------------------------- case SPELL_CURSE: if (spells[i].pSpellFx) { CCurse * curse=(CCurse *)spells[i].pSpellFx; EERIE_3D target; Vector_Init(&target); if ((spells[i].target>=0) && (inter.iobj[spells[i].target])) { target.x=inter.iobj[spells[i].target]->pos.x; target.y=inter.iobj[spells[i].target]->pos.y; target.z=inter.iobj[spells[i].target]->pos.z; if (spells[i].target==0) target.y-=200.f; else target.y+=inter.iobj[spells[i].target]->physics.cyl.height-30.f; } ARX_CHECK_ULONG(FrameDiff); curse->Update(ARX_CLEAN_WARN_CAST_ULONG(FrameDiff)); curse->Render(m_pd3dDevice, &target); SETCULL(GDevice,D3DCULL_NONE); } break; //----------------------------------------------------------------------------------------- case SPELL_FIRE_PROTECTION: spells[i].pSpellFx->Update(FrameDiff); spells[i].pSpellFx->Render(m_pd3dDevice); break; //----------------------------------------------------------------------------------------- case SPELL_COLD_PROTECTION: spells[i].pSpellFx->Update(FrameDiff); spells[i].pSpellFx->Render(m_pd3dDevice); break; //----------------------------------------------------------------------------------------- //***************************************************************************************** // LEVEL 5 SPELLS ----------------------------------------------------------------------------- //----------------------------------------------------------------------------------------- case SPELL_CURE_POISON: { if (spells[i].pSpellFx) { spells[i].pSpellFx->Update(FrameDiff); spells[i].pSpellFx->Render(m_pd3dDevice); } } break; //----------------------------------------------------------------------------------------- case SPELL_RUNE_OF_GUARDING: { if (spells[i].pSpellFx) { spells[i].pSpellFx->Update(FrameDiff); spells[i].pSpellFx->Render(m_pd3dDevice); CRuneOfGuarding * pCRG=(CRuneOfGuarding *)spells[i].pSpellFx; if (pCRG) { EERIE_SPHERE sphere; sphere.origin.x=pCRG->eSrc.x; sphere.origin.y=pCRG->eSrc.y; sphere.origin.z=pCRG->eSrc.z; sphere.radius=__max(spells[i].caster_level*15.f,50.f); if (CheckAnythingInSphere(&sphere,spells[i].caster,CAS_NO_SAME_GROUP | CAS_NO_BACKGROUND_COL | CAS_NO_ITEM_COL| CAS_NO_FIX_COL | CAS_NO_DEAD_COL)) { ARX_BOOMS_Add(&pCRG->eSrc); LaunchFireballBoom(&pCRG->eSrc,(float)spells[i].caster_level); DoSphericDamage(&pCRG->eSrc,4.f*spells[i].caster_level,30.f*spells[i].caster_level,DAMAGE_AREA,DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL,spells[i].caster); spells[i].tolive=0; ARX_SOUND_PlaySFX(SND_SPELL_FIRE_HIT, &sphere.origin); } } } } break; case SPELL_REPEL_UNDEAD: { if (spells[i].pSpellFx) { spells[i].pSpellFx->Update(FrameDiff); spells[i].pSpellFx->Render(m_pd3dDevice); if (spells[i].target == 0) ARX_SOUND_RefreshPosition(spells[i].snd_loop); } } break; //----------------------------------------------------------------------------------------- case SPELL_POISON_PROJECTILE: if (spells[i].pSpellFx) { spells[i].pSpellFx->Update(FrameDiff); spells[i].pSpellFx->Render(m_pd3dDevice); } break; //----------------------------------------------------------------------------------------- case SPELL_LEVITATE: { CLevitate *pLevitate=(CLevitate *)spells[i].pSpellFx; EERIE_3D target; if (spells[i].target==0) { target.x=player.pos.x; target.y=player.pos.y+150.f; target.z=player.pos.z; player.levitate=1; } else { target.x=inter.iobj[spells[i].caster]->pos.x; target.y = inter.iobj[spells[i].caster]->pos.y; target.z=inter.iobj[spells[i].caster]->pos.z; } pLevitate->ChangePos(&target); CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { pCSpellFX->Update(FrameDiff); pCSpellFX->Render(m_pd3dDevice); SETCULL(GDevice,D3DCULL_NONE); } } break; //----------------------------------------------------------------------------------------- //***************************************************************************************** // LEVEL 6 SPELLS ----------------------------------------------------------------------------- case SPELL_RISE_DEAD: { CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { if (spells[i].longinfo==-2) { pCSpellFX->lLightId=-1; break; } spells[i].tolive+=200; pCSpellFX->Update(FrameDiff); pCSpellFX->Render(m_pd3dDevice); if (pCSpellFX->lLightId > -1) { long id=pCSpellFX->lLightId; DynLight[id].exist=1; DynLight[id].intensity = 0.7f + 2.3f; DynLight[id].fallend = 500.f; DynLight[id].fallstart = 400.f; DynLight[id].rgb.r = 0.8f; DynLight[id].rgb.g = 0.2f; DynLight[id].rgb.b = 0.2f; DynLight[id].duration=800; DynLight[id].time_creation = ARXTimeUL(); } unsigned long tim=pCSpellFX->GetCurrentTime(); if ((tim>3000) && (spells[i].longinfo==-1)) { ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, &spells[i].caster_pos); char tmptext[256]; CRiseDead *prise; prise= (CRiseDead *)spells[i].pSpellFx; if (prise) { EERIE_CYLINDER phys; phys.height=-200; phys.radius=50; phys.origin.x=spells[i].target_pos.x; phys.origin.y=spells[i].target_pos.y; phys.origin.z=spells[i].target_pos.z; float anything = CheckAnythingInCylinder(&phys, NULL, CFLAG_JUST_TEST); if (EEfabs(anything)<30) { sprintf(tmptext,"%sGraph\\Obj3D\\Interactive\\NPC\\Undead_base\\Undead_base.asl",Project.workingdir); INTERACTIVE_OBJ * io; io=AddNPC(m_pd3dDevice,tmptext,IO_IMMEDIATELOAD); if (io) { ARX_INTERACTIVE_HideGore(io); RestoreInitialIOStatusOfIO(io); long lSpellsCaster = spells[i].caster ; ARX_CHECK_SHORT(lSpellsCaster); io->summoner=ARX_CLEAN_WARN_CAST_SHORT(lSpellsCaster); io->ioflags|=IO_NOSAVE; spells[i].longinfo=GetInterNum(io); io->scriptload=1; ARX_INTERACTIVE_Teleport(io,&phys.origin,0); MakeTemporaryIOIdent(io); SendInitScriptEvent(io); if ((spells[i].caster>=0) && (spells[i].castereSrc.x+rnd()*100.f-50.f; pos.y=prise->eSrc.y+100+rnd()*100.f-50.f; pos.z=prise->eSrc.z+rnd()*100.f-50.f; MakeCoolFx(&pos); } } pCSpellFX->lLightId=-1; } else { ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE); spells[i].longinfo=-2; spells[i].tolive=0; } } } else if ((!ARXPausedTimer) && (tim<4000)) { if (rnd()>0.95f) { CRiseDead *pRD = (CRiseDead*)pCSpellFX; EERIE_3D pos; pos.x = pRD->eSrc.x; pos.y = pRD->eSrc.y; pos.z = pRD->eSrc.z; MakeCoolFx(&pos); } } } } break; //----------------------------------------------------------------------------------------- case SPELL_SLOW_DOWN: { CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { pCSpellFX->Update(FrameDiff); pCSpellFX->Render(m_pd3dDevice); } } break; case SPELL_DISARM_TRAP: { } break; case SPELL_PARALYSE: break; case SPELL_CREATE_FIELD: { CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { if (ValidIONum(spells[i].longinfo)) { INTERACTIVE_OBJ * io=inter.iobj[spells[i].longinfo]; CCreateField * ccf=(CCreateField *)pCSpellFX; io->pos.x = ccf->eSrc.x; io->pos.y = ccf->eSrc.y; io->pos.z = ccf->eSrc.z; if (IsAnyNPCInPlatform(io)) { spells[i].tolive=0; } pCSpellFX->Update(FrameDiff); if (VisibleSphere(ccf->eSrc.x,ccf->eSrc.y-120.f,ccf->eSrc.z,400.f)) pCSpellFX->Render(m_pd3dDevice); } } } break; //----------------------------------------------------------------------------------------- //***************************************************************************************** // LEVEL 7 SPELLS ----------------------------------------------------------------------------- case SPELL_CONFUSE: { CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { pCSpellFX->Update(FrameDiff); pCSpellFX->Render(m_pd3dDevice); } } break; case SPELL_FIRE_FIELD: { CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { CFireField *pf = (CFireField *) pCSpellFX; pCSpellFX->Update(FrameDiff); if (spells[i].longinfo2==-1) spells[i].longinfo2=GetFreeDynLight(); if (spells[i].longinfo2!=-1) { EERIE_LIGHT * el=&DynLight[spells[i].longinfo2]; el->pos.x = pf->pos.x; el->pos.y = pf->pos.y-120.f; el->pos.z = pf->pos.z; el->exist = 1; el->intensity = 4.6f; el->fallstart = 150.f+rnd()*30.f; el->fallend = 290.f+rnd()*30.f; el->rgb.r = 1.f-rnd()*DIV10; el->rgb.g = 0.8f; el->rgb.b = 0.6f; el->duration = 600; el->extras=0; } if (VisibleSphere(pf->pos.x,pf->pos.y-120.f,pf->pos.z,350.f)) { pCSpellFX->Render(m_pd3dDevice); float fDiff = FrameDiff/8.f ; ARX_CHECK_INT(fDiff); int nTime = ARX_CLEAN_WARN_CAST_INT(fDiff); for (long nn=0;nn<=nTime+1;nn++) { long j=ARX_PARTICLES_GetFree(); if ((j!=-1) && (!ARXPausedTimer) ) { ParticleCount++; PARTICLE_DEF * pd=&particle[j]; pd->exist=TRUE; pd->zdec=0; float sy=rnd()*3.14159f*2.f-3.14159f; float sx=EEsin(sy); float sz=EEcos(sy); sy=EEsin(sy); pd->ov.x=pf->pos.x+120.f*sx*rnd(); pd->ov.y=pf->pos.y+15.f*sy*rnd(); pd->ov.z=pf->pos.z+120.f*sz*rnd(); pd->move.x=(2.f-4.f*rnd()); pd->move.y=(1.f-8.f*rnd()); pd->move.z=(2.f-4.f*rnd()); pd->siz = 7.f; pd->tolive = 500+(unsigned long)(rnd()*1000.f); pd->special = 0; pd->tc = fire2; pd->special |= ROTATING | MODULATE_ROTATION | FIRE_TO_SMOKE; pd->fparam = 0.1f-rnd()*0.2f; pd->scale.x = -8.f; pd->scale.y = -8.f; pd->scale.z = -8.f; pd->timcreation = lARXTime; pd->r = pd->g = pd->b = 1.f; long j2 = ARX_PARTICLES_GetFree(); if (j2!=-1) { ParticleCount++; PARTICLE_DEF * pd2=&particle[j2]; memcpy(pd2,pd,sizeof(PARTICLE_DEF)); pd2->delay=(long)(float)(rnd()*150.f+60.f); } } } } } } break; case SPELL_ICE_FIELD: { CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { pCSpellFX->Update(FrameDiff); CIceField *pf = (CIceField *) pCSpellFX; if (spells[i].longinfo2==-1) spells[i].longinfo2=GetFreeDynLight(); if (spells[i].longinfo2!=-1) { EERIE_LIGHT * el=&DynLight[spells[i].longinfo2]; el->pos.x = pf->eSrc.x; el->pos.y = pf->eSrc.y-120.f; el->pos.z = pf->eSrc.z; el->exist = 1; el->intensity = 4.6f; el->fallstart = 150.f+rnd()*30.f; el->fallend = 290.f+rnd()*30.f; el->rgb.r = 0.76f; el->rgb.g = 0.76f; el->rgb.b = 1.0f-rnd()*DIV10; el->duration = 600; el->extras=0; } if (VisibleSphere(pf->eSrc.x,pf->eSrc.y-120.f,pf->eSrc.z,350.f)) { pCSpellFX->Render(m_pd3dDevice); } } SETCULL(GDevice,D3DCULL_NONE); } break; //----------------------------------------------------------------------------------------- case SPELL_LIGHTNING_STRIKE: { CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { pCSpellFX->Update(FrameDiff); pCSpellFX->Render(m_pd3dDevice); } } break; //----------------------------------------------------------------------------------------- //***************************************************************************************** // LEVEL 8 SPELLS ----------------------------------------------------------------------------- case SPELL_ENCHANT_WEAPON: { CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { pCSpellFX->Update(FrameDiff); pCSpellFX->Render(m_pd3dDevice); } } case SPELL_EXPLOSION: { if (spells[i].longinfo2 == -1) spells[i].longinfo2=GetFreeDynLight(); if (spells[i].longinfo2 != -1) { long id = spells[i].longinfo2; DynLight[id].rgb.r = 0.1f+rnd()*DIV3;; DynLight[id].rgb.g = 0.1f+rnd()*DIV3;; DynLight[id].rgb.b = 0.8f+rnd()*DIV5;; DynLight[id].duration=200; long lvl; float rr,r2; EERIE_3D pos; if (rnd()>0.8f) { F2L((rnd()*9.f+4.f),&lvl); rr=DEG2RAD(rnd()*360.f); r2=DEG2RAD(rnd()*360.f); pos.x=DynLight[id].pos.x-EEsin(rr)*260; pos.y=DynLight[id].pos.y-EEsin(r2)*260; pos.z=DynLight[id].pos.z+EEcos(rr)*260; EERIE_RGB rgb; rgb.r=0.1f+rnd()*DIV3; rgb.g=0.1f+rnd()*DIV3; rgb.b=0.8f+rnd()*DIV5; LaunchFireballBoom(&pos, ARX_CLEAN_WARN_CAST_FLOAT(lvl), NULL, &rgb); } else if (rnd()>0.76f) { F2L((rnd()*9.f+4.f),&lvl); rr=DEG2RAD(rnd()*360.f); r2=DEG2RAD(rnd()*360.f); pos.x=DynLight[id].pos.x-EEsin(rr)*260; pos.y=DynLight[id].pos.y-EEsin(r2)*260; pos.z=DynLight[id].pos.z+EEcos(rr)*260; MakeCoolFx(&pos); } else if (rnd()>0.66f) { F2L((rnd()*9.f+4.f),&lvl); rr=DEG2RAD(rnd()*360.f); r2=DEG2RAD(rnd()*360.f); pos.x=DynLight[id].pos.x-EEsin(rr)*160; pos.y=DynLight[id].pos.y-EEsin(r2)*160; pos.z=DynLight[id].pos.z+EEcos(rr)*160; ARX_PARTICLES_Add_Smoke(&pos,2,20); // flag 1 = randomize pos } } } break; //----------------------------------------------------------------------------------------- //***************************************************************************************** // LEVEL 9 SPELLS ------------------------------------------------------------------------- //----------------------------------------------------------------------------------------- case SPELL_SUMMON_CREATURE: { if (!ARXPausedTimer) { if ((float)ARXTime-(float)spells[i].timcreation<=4000) { if (rnd()>0.7f) { EERIE_3D pos; CSummonCreature *pSummon; pSummon= (CSummonCreature *)spells[i].pSpellFx; if (pSummon) { pos.x=pSummon->eSrc.x; pos.y=pSummon->eSrc.y; pos.z=pSummon->eSrc.z; MakeCoolFx(&pos); } } CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { pCSpellFX->Update(FrameDiff); pCSpellFX->Render(m_pd3dDevice); } spells[i].longinfo=1; spells[i].longinfo2=-1; } else if (spells[i].longinfo) { if (spells[i].pSpellFx->lLightId > -1) { long id = spells[i].pSpellFx->lLightId; DynLight[id].exist = 0; spells[i].pSpellFx->lLightId=-1; } spells[i].longinfo=0; ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, &spells[i].caster_pos); char tmptext[256]; CSummonCreature *pSummon; pSummon= (CSummonCreature *)spells[i].pSpellFx; if (pSummon) { EERIE_CYLINDER phys; phys.height=-200; phys.radius=50; phys.origin.x=spells[i].target_pos.x; phys.origin.y=spells[i].target_pos.y; phys.origin.z=spells[i].target_pos.z; float anything = CheckAnythingInCylinder(&phys, NULL, CFLAG_JUST_TEST); if (EEfabs(anything)<30) { long tokeep=0; if (spells[i].caster_level>=9) { tokeep=1; sprintf(tmptext,"%sGraph\\Obj3D\\Interactive\\NPC\\Demon\\Demon.asl",Project.workingdir); } else { tokeep=0; if (rnd()>0.98f) { sprintf(tmptext,"%sGraph\\Obj3D\\Interactive\\NPC\\WRat_base\\WRat_base.asl",Project.workingdir); tokeep=-1; } else sprintf(tmptext,"%sGraph\\Obj3D\\Interactive\\NPC\\Chicken_Base\\Chicken_Base.asl",Project.workingdir); } if ((rnd()>0.997f) || ((cur_rf>=3) && (rnd()>0.8f)) || ((cur_mr>=3) && (rnd()>0.3f))) { sprintf(tmptext,"%sGraph\\Obj3D\\Interactive\\NPC\\WRat_base\\WRat_base.asl",Project.workingdir); tokeep=-1; } if ((rnd()>0.997f) || (sp_max && (rnd()>0.8f)) || ((cur_mr>=3) && (rnd()>0.3f))) { sprintf(tmptext,"%sGraph\\Obj3D\\Interactive\\NPC\\Y_mx\\Y_mx.asl",Project.workingdir); tokeep=0; } if (spells[i].fdata==1.f) { if (rnd()>0.5) { sprintf(tmptext,"%sGraph\\Obj3D\\Interactive\\NPC\\WRat_base\\WRat_base.asl",Project.workingdir); tokeep=-1; } else { sprintf(tmptext,"%sGraph\\Obj3D\\Interactive\\NPC\\Y_mx\\Y_mx.asl",Project.workingdir); tokeep=0; } } INTERACTIVE_OBJ * io; io=AddNPC(m_pd3dDevice,tmptext,IO_IMMEDIATELOAD); if (!io) { sprintf(tmptext,"%sGraph\\Obj3D\\Interactive\\NPC\\Chicken_Base\\Chicken_Base.asl",Project.workingdir); tokeep=0; io=AddNPC(m_pd3dDevice,tmptext,IO_IMMEDIATELOAD); } if (io) { RestoreInitialIOStatusOfIO(io); long lSpellsCaster = spells[i].caster ; ARX_CHECK_SHORT(lSpellsCaster); io->summoner=ARX_CLEAN_WARN_CAST_SHORT(lSpellsCaster); io->scriptload=1; if (tokeep==1) io->ioflags|=IO_NOSAVE; io->pos.x = phys.origin.x; io->pos.y = phys.origin.y; io->pos.z = phys.origin.z; MakeTemporaryIOIdent(io); SendInitScriptEvent(io); if (tokeep<0) { io->scale=1.65f; io->physics.cyl.radius=25; io->physics.cyl.height=-43; io->speed_modif=1.f; } if ((spells[i].caster>=0) && (spells[i].castereSrc.x+rnd()*100.f-50.f; pos.y=pSummon->eSrc.y+100+rnd()*100.f-50.f; pos.z=pSummon->eSrc.z+rnd()*100.f-50.f; MakeCoolFx(&pos); } if (tokeep==1) spells[i].longinfo2=GetInterNum(io); else spells[i].longinfo2=-1; } } } } else if (spells[i].longinfo2<=0) { spells[i].tolive=0; } } } break; case SPELL_FAKE_SUMMON: { if (!ARXPausedTimer) if (rnd()>0.7f) { EERIE_3D pos; CSummonCreature *pSummon; pSummon= (CSummonCreature *)spells[i].pSpellFx; if (pSummon) { pos.x=pSummon->eSrc.x; pos.y=pSummon->eSrc.y; pos.z=pSummon->eSrc.z; MakeCoolFx(&pos); } } CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { pCSpellFX->Update(FrameDiff); pCSpellFX->Render(m_pd3dDevice); } } break; //----------------------------------------------------------------------------------------- case SPELL_INCINERATE: { if (ValidIONum(spells[i].caster)) { ARX_SOUND_RefreshPosition(spells[i].snd_loop, &inter.iobj[spells[i].caster]->pos); } } break; case SPELL_NEGATE_MAGIC: { if (ValidIONum(spells[i].target)) LaunchAntiMagicField(&inter.iobj[spells[i].target]->pos,i); CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { pCSpellFX->Update(FrameDiff); pCSpellFX->Render(m_pd3dDevice); } } break; case SPELL_MASS_PARALYSE: break; //******************************************************************************************* // LEVEL 10 SPELLS ----------------------------------------------------------------------------- //----------------------------------------------------------------------------------------- case SPELL_FREEZE_TIME: { } break; //----------------------------------------------------------------------------------------- case SPELL_CONTROL_TARGET: { CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { pCSpellFX->Update(FrameDiff); pCSpellFX->Render(m_pd3dDevice); } } break; case SPELL_MASS_INCINERATE: { if (ValidIONum(spells[i].caster)) { ARX_SOUND_RefreshPosition(spells[i].snd_loop, &inter.iobj[spells[i].caster]->pos); } } break; //----------------------------------------------------------------------------------------- case SPELL_MASS_LIGHTNING_STRIKE: { CSpellFx *pCSpellFX = spells[i].pSpellFx; if (pCSpellFX) { pCSpellFX->Update(FrameDiff); pCSpellFX->Render(m_pd3dDevice); } EERIE_3D _source; _source.x=spells[i].vsource.x; _source.y=spells[i].vsource.y; _source.z=spells[i].vsource.z; float _fx; _fx = 0.5f; unsigned long _gct; _gct = 0; EERIE_3D position; spells[i].lastupdate=tim; position.x=_source.x+rnd()*500.f-250.f; position.y=_source.y+rnd()*500.f-250.f; position.z=_source.z+rnd()*500.f-250.f; ARX_SOUND_RefreshPosition(spells[i].snd_loop, &position); ARX_SOUND_RefreshVolume(spells[i].snd_loop, _fx + 0.5F); ARX_SOUND_RefreshPitch(spells[i].snd_loop, 0.8F + 0.4F * rnd()); if (rnd()>0.62f) { position.x=_source.x+rnd()*500.f-250.f; position.y=_source.y+rnd()*500.f-250.f; position.z=_source.z+rnd()*500.f-250.f; ARX_SOUND_PlaySFX(SND_SPELL_SPARK, &position, 0.8F + 0.4F * rnd()); } if (rnd()>0.82f) { position.x=_source.x+rnd()*500.f-250.f; position.y=_source.y+rnd()*500.f-250.f; position.z=_source.z+rnd()*500.f-250.f; ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, &position, 0.8F + 0.4F * rnd()); } if ((_gct>spells[i].tolive-1800) && (spells[i].siz==0)) { spells[i].siz=1; ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, NULL, 0.8F + 0.4F * rnd()); } if (spells[i].longinfo!=-1) { float fxx; if (_fx>0.2f) fxx=1.f; else fxx=_fx*5.f; DynLight[spells[i].longinfo].intensity=1.3f+rnd()*1.f; DynLight[spells[i].longinfo].fallend=850.f; DynLight[spells[i].longinfo].fallstart=500.f; DynLight[spells[i].longinfo].rgb.r=1.f*fxx; DynLight[spells[i].longinfo].rgb.g=0.f*fxx; DynLight[spells[i].longinfo].rgb.b=0.f*fxx; } } break; //----------------------------------------------------------------------------------------- case SPELL_TELEPORT: { TELEPORT=(float)(((float)tim-(float)spells[i].timcreation)/(float)spells[i].tolive); if ((LASTTELEPORT<0.5f) && (TELEPORT>=0.5f)) { EERIE_3D pos; pos.x=lastteleport.x; pos.y=lastteleport.y; pos.z=lastteleport.z; lastteleport.x=player.pos.x; lastteleport.y=player.pos.y; lastteleport.z=player.pos.z; player.pos.x=pos.x; player.pos.y=pos.y; player.pos.z=pos.z; LASTTELEPORT=32.f; ARX_SOUND_PlaySFX(SND_SPELL_TELEPORTED, &player.pos); } else LASTTELEPORT=TELEPORT; if (TELEPORT>=0.5f) { TELEPORT=1.f-(TELEPORT-0.5f)*2.f; } else TELEPORT*=2.f; } break; //----------------------------------------------------------------------------------------- case SPELL_MAGIC_SIGHT: if (spells[i].caster == 0) { ARX_SOUND_RefreshPosition(spells[i].snd_loop); if (subj.focal>IMPROVED_FOCAL) subj.focal-=DEC_FOCAL; } break; //----------------------------------------------------------------------------------------- case SPELL_TELEKINESIS: break; //----------------------------------------------------------------------------------------- case SPELL_INVISIBILITY: if (spells[i].target!=0) { if (!(inter.iobj[spells[i].target]->GameFlags & GFLAG_INVISIBILITY)) { ARX_SPELLS_RemoveSpellOn(spells[i].target,i); ARX_SPELLS_Fizzle(i); } } break; //----------------------------------------------------------------------------------------- case SPELL_MANA_DRAIN: { if ( (cabal!=NULL) ) { float refpos; float scaley; if (spells[i].caster==0) scaley=90.f; else scaley=EEfabs(inter.iobj[spells[i].caster]->physics.cyl.height*DIV2)+30.f; float mov1=EEsin((float)LastFrameTime*DIV800)*scaley; float mov=EEsin((float)FrameTime*DIV800)*scaley; if ((mov1scaley-10.f)) ARX_SOUND_PlaySFX(SND_SPELL_MAGICAL_SHIELD, &spells[i].caster_pos, 0.4F); if ((mov1>-scaley+10.f) && (mov<-scaley+10.f)) ARX_SOUND_PlaySFX(SND_SPELL_MAGICAL_SHIELD, &spells[i].caster_pos, 0.4F); if (spells[i].caster==0) { cabalpos.x = player.pos.x; cabalpos.y=player.pos.y+60.f-mov; cabalpos.z = player.pos.z; refpos=player.pos.y+60.f; } else { cabalpos.x = inter.iobj[spells[i].caster]->pos.x; cabalpos.y=inter.iobj[spells[i].caster]->pos.y-scaley-mov; cabalpos.z = inter.iobj[spells[i].caster]->pos.z; refpos=inter.iobj[spells[i].caster]->pos.y-scaley; } float Es=EEsin((float)FrameTime*DIV800 + DEG2RAD(scaley)); if (spells[i].longinfo2!=-1) { DynLight[spells[i].longinfo2].pos.x = cabalpos.x; DynLight[spells[i].longinfo2].pos.y = refpos; DynLight[spells[i].longinfo2].pos.z = cabalpos.z; DynLight[spells[i].longinfo2].rgb.b=rnd()*0.2f+0.8f; DynLight[spells[i].longinfo2].fallstart=Es*1.5f; } GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE ); SETALPHABLEND(GDevice,TRUE); SETZWRITE(GDevice, FALSE ); cabalangle.b=spells[i].fdata+(float)FrameDiff*0.1f; spells[i].fdata=cabalangle.b; cabalangle.g = 0.f; cabalcolor.r = cabalcolor.g = 0.4f; cabalcolor.b = 0.8f; cabalscale.z=cabalscale.y=cabalscale.x=Es; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); mov=EEsin((float)(FrameTime-30.f)*DIV800)*scaley; cabalpos.y=refpos-mov; cabalcolor.r = cabalcolor.g = 0.2f; cabalcolor.b = 0.5f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); mov=EEsin((float)(FrameTime-60.f)*DIV800)*scaley; cabalpos.y=refpos-mov; cabalcolor.r = cabalcolor.g = 0.1f; cabalcolor.b = 0.25f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); mov=EEsin((float)(FrameTime-120.f)*DIV800)*scaley; cabalpos.y=refpos-mov; cabalcolor.r = cabalcolor.g = 0.f; cabalcolor.b = 0.15f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); cabalangle.b=-cabalangle.b; cabalpos.y=refpos-mov; cabalscale.x=cabalscale.y=cabalscale.z=Es; cabalcolor.r = cabalcolor.g = 0.f; cabalcolor.b = 0.15f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); mov=EEsin((float)(FrameTime+30.f)*DIV800)*scaley; cabalpos.y=refpos+mov; cabalcolor.r = cabalcolor.g = 0.1f; cabalcolor.b = 0.25f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); mov=EEsin((float)(FrameTime+60.f)*DIV800)*scaley; cabalpos.y=refpos+mov; cabalcolor.r = cabalcolor.g = 0.2f; cabalcolor.b = 0.5f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); mov=EEsin((float)(FrameTime+120.f)*DIV800)*scaley; cabalpos.y=refpos+mov; cabalcolor.r = cabalcolor.g = 0.4f; cabalcolor.b = 0.8f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); cabalangle.b=-cabalangle.b; SETALPHABLEND(GDevice,FALSE); SETZWRITE(GDevice, TRUE ); ARX_SOUND_RefreshPosition(spells[i].snd_loop, &cabalpos); } } break; //----------------------------------------------------------------------------------------- case SPELL_LIFE_DRAIN: { if ( (cabal!=NULL) ) { float refpos; float scaley; if (spells[i].caster==0) scaley=90.f; else scaley=EEfabs(inter.iobj[spells[i].caster]->physics.cyl.height*DIV2)+30.f; float mov=EEsin((float)FrameTime*DIV800)*scaley; if (spells[i].caster==0) { cabalpos.x = player.pos.x; cabalpos.y=player.pos.y+60.f-mov; cabalpos.z = player.pos.z; refpos=player.pos.y+60.f; } else { cabalpos.x = inter.iobj[spells[i].caster]->pos.x; cabalpos.y=inter.iobj[spells[i].caster]->pos.y-scaley-mov; cabalpos.z = inter.iobj[spells[i].caster]->pos.z; refpos=inter.iobj[spells[i].caster]->pos.y-scaley; } float Es=EEsin((float)FrameTime*DIV800 + DEG2RAD(scaley)); if (spells[i].longinfo2!=-1) { DynLight[spells[i].longinfo2].pos.x = cabalpos.x; DynLight[spells[i].longinfo2].pos.y = refpos; DynLight[spells[i].longinfo2].pos.z = cabalpos.z; DynLight[spells[i].longinfo2].rgb.r=rnd()*0.2f+0.8f; DynLight[spells[i].longinfo2].fallstart=Es*1.5f; } SETCULL(GDevice,D3DCULL_NONE); GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE ); SETALPHABLEND(GDevice,TRUE); SETZWRITE(GDevice, FALSE ); cabalangle.b=spells[i].fdata+(float)FrameDiff*0.1f; spells[i].fdata=cabalangle.b; cabalangle.g = 0.f; cabalcolor.r = 0.8f; cabalcolor.g = 0.f; cabalcolor.b = 0.f; cabalscale.z=cabalscale.y=cabalscale.x=Es; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); mov=EEsin((float)(FrameTime-30.f)*DIV800)*scaley; cabalpos.y=refpos-mov; cabalcolor.b = cabalcolor.g = 0.f; cabalcolor.r = 0.5f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); mov=EEsin((float)(FrameTime-60.f)*DIV800)*scaley; cabalpos.y=refpos-mov; cabalcolor.b = cabalcolor.g = 0.f; cabalcolor.r = 0.25f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); mov=EEsin((float)(FrameTime-120.f)*DIV800)*scaley; cabalpos.y=refpos-mov; cabalcolor.b = cabalcolor.g = 0.f; cabalcolor.r = 0.15f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); cabalangle.b=-cabalangle.b; cabalpos.y=refpos-mov; cabalscale.x=cabalscale.y=cabalscale.z=Es; cabalcolor.b = cabalcolor.g = 0.f; cabalcolor.r = 0.15f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); mov=EEsin((float)(FrameTime+30.f)*DIV800)*scaley; cabalpos.y=refpos+mov; cabalcolor.b = cabalcolor.g = 0.f; cabalcolor.r = 0.25f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); mov=EEsin((float)(FrameTime+60.f)*DIV800)*scaley; cabalpos.y=refpos+mov; cabalcolor.b = cabalcolor.g = 0.f; cabalcolor.r = 0.5f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); mov=EEsin((float)(FrameTime+120.f)*DIV800)*scaley; cabalpos.y=refpos+mov; cabalcolor.b = cabalcolor.g = 0.f; cabalcolor.r = 0.8f; DrawEERIEObjEx(GDevice,cabal,&cabalangle,&cabalpos,&cabalscale,&cabalcolor); cabalangle.b=-cabalangle.b; SETALPHABLEND(GDevice,FALSE); SETZWRITE(GDevice, TRUE ); ARX_SOUND_RefreshPosition(spells[i].snd_loop, &cabalpos); } } break; //----------------------------------------------------------------------------------------- case SPELL_FLYING_EYE: { eyeball.floating=EEsin((spells[i].lastupdate-spells[i].timcreation)*DIV1000)*10.f; if (spells[i].lastupdate-spells[i].timcreation<=3000) { F2L((float)(spells[i].lastupdate-spells[i].timcreation)*DIV30,&eyeball.exist); float d=(float)eyeball.exist*DIV100; eyeball.size.x = 1.f - d; eyeball.size.y = 1.f - d; eyeball.size.z = 1.f - d; eyeball.angle.b+=framediff3*DIV10*6.f; } else { eyeball.exist=2; } spells[i].lastupdate=tim; } break; } } } if( bSoftRender ) SET_FORCE_NO_VB( bNoVB ); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// void TryToCastSpell(INTERACTIVE_OBJ * io, const long &spellid, const long &level, const long &target, const long &flags, const long &duration) { if (!io || io->spellcast_data.castingspell >= 0) return; if (!(flags & SPELLCAST_FLAG_NOMANA) && (io->ioflags & IO_NPC) && (io->_npcdata->mana<=0.f)) return; unsigned long i(0); for (; i < SPELL_COUNT; i++) if (spellicons[i].spellid == spellid) break; if ( i >= SPELL_COUNT) return; // not an existing spell... for (unsigned long j(0); j < 4; j++) io->spellcast_data.symb[j] = 255; // checks for symbol drawing... if (!(flags & SPELLCAST_FLAG_NOANIM) && io->ioflags & IO_NPC) { ANIM_USE *ause1 = &io->animlayer[1]; AcquireLastAnim(io); FinishAnim(io, ause1->cur_anim); ANIM_Set(ause1, io->anims[ANIM_CAST_START]); for (unsigned long j(0); j < 4; j++) io->spellcast_data.symb[j] = spellicons[i].symbols[j]; } io->spellcast_data.castingspell = spellid; ARX_CHECK_SHORT(flags); ARX_CHECK_SHORT(level); io->spellcast_data.spell_flags = ARX_CLEAN_WARN_CAST_SHORT(flags); io->spellcast_data.spell_level = ARX_CLEAN_WARN_CAST_SHORT(level); io->spellcast_data.duration = duration; io->spellcast_data.target = target; io->GameFlags &=~GFLAG_INVISIBILITY; if ( ((io->spellcast_data.spell_flags & SPELLCAST_FLAG_NOANIM) && (io->spellcast_data.spell_flags & SPELLCAST_FLAG_NODRAW) ) || (io->spellcast_data.spell_flags & SPELLCAST_FLAG_PRECAST)) { ARX_SPELLS_Launch(io->spellcast_data.castingspell,GetInterNum(io),io->spellcast_data.spell_flags,io->spellcast_data.spell_level,io->spellcast_data.target,io->spellcast_data.duration); io->spellcast_data.castingspell=-1; } io->spellcast_data.spell_flags &=~SPELLCAST_FLAG_NODRAW; // temporary, removes colored flares } void ApplySPWep() { if (!sp_wep) { ARX_SPSound(); char tex[256]; char tex2[256]; sprintf(tex2,"%sGraph\\Obj3D\\Interactive\\Items\\Weapons\\sword_mx\\sword_mx.teo",Project.workingdir); File_Standardize(tex2,tex); INTERACTIVE_OBJ * ioo=(INTERACTIVE_OBJ *)AddItem(GDevice,tex,IO_IMMEDIATELOAD); if (ioo!=NULL) { sp_wep=1; MakeCoolFx(&player.pos); MakeCoolFx(&player.pos); ioo->scriptload=1; MakeTemporaryIOIdent(ioo); SendInitScriptEvent(ioo); ioo->show=SHOW_FLAG_IN_INVENTORY; if (!CanBePutInInventory(ioo)) { PutInFrontOfPlayer(ioo,1); } MakeSpCol(); strcpy(sp_max_ch,"!!!_Grosbillite_!!!"); sp_max_nb=strlen(sp_max_ch); sp_max_start=ARX_TIME_Get(); } } } void MakeSpCol() { ARX_SPSound(); for (long i=0;i<64;i++) { sp_max_y[i]=0; } sp_max_col[0]=0x00FF0000; sp_max_col[1]=0x0000FF00; sp_max_col[2]=0x000000FF; sp_max_col[3]=0x00FFFF00; sp_max_col[4]=0x00FF00FF; sp_max_col[5]=0x0000FFFF; sp_max_col[6]=0x00FF0000; sp_max_col[7]=0x0000FF00; sp_max_col[8]=0x000000FF; sp_max_col[9]=0x00FFFF00; sp_max_col[10]=0x00FF00FF; sp_max_col[11]=0x0000FFFF; sp_max_col[12]=0x00FF0000; sp_max_col[13]=0x0000FF00; sp_max_col[14]=0x000000FF; sp_max_col[15]=0x00FFFF00; sp_max_col[16]=0x00FF00FF; sp_max_col[17]=0x0000FFFF; sp_max_col[18]=0x00FF0000; sp_max_col[19]=0x0000FF00; sp_max_col[20]=0x000000FF; sp_max_col[21]=0x00FFFF00; sp_max_col[22]=0x00FF00FF; sp_max_col[23]=0x0000FFFF; sp_max_col[24]=0x00FFFF00; sp_max_col[25]=0x00FF00FF; sp_max_col[26]=0x0000FFFF; sp_max_col[27]=0x00FF0000; sp_max_col[28]=0x0000FF00; sp_max_col[29]=0x000000FF; sp_max_col[30]=0x00FFFF00; sp_max_col[31]=0x00FF00FF; sp_max_col[32]=0x0000FFFF; } void ApplyCurSOS() { MakeSpCol(); ARX_MINIMAP_Reveal(); strcpy(sp_max_ch,"!!!_Temple of Elemental Lavis_!!!"); sp_max_nb=strlen(sp_max_ch); sp_max_start=ARX_TIME_Get(); } void ApplySPBow() { { ARX_SPSound(); char tex[256]; char tex2[256]; sprintf(tex2,"%sGraph\\Obj3D\\Interactive\\Items\\Weapons\\bow_mx\\bow_mx.teo",Project.workingdir); File_Standardize(tex2,tex); INTERACTIVE_OBJ * ioo=(INTERACTIVE_OBJ *)AddItem(GDevice,tex,IO_IMMEDIATELOAD); if (ioo!=NULL) { MakeCoolFx(&player.pos); MakeCoolFx(&player.pos); ioo->scriptload=1; MakeTemporaryIOIdent(ioo); SendInitScriptEvent(ioo); ioo->show=SHOW_FLAG_IN_INVENTORY; if (!CanBePutInInventory(ioo)) { PutInFrontOfPlayer(ioo,1); } MakeSpCol(); strcpy(sp_max_ch,"!!!_Bow to Samy & Anne_!!!"); sp_max_nb=strlen(sp_max_ch); sp_max_start=ARX_TIME_Get(); } } } void ApplySPArm() { ARX_SPSound(); char tex[256]; char tex2[256]; switch (sp_arm) { case 0: sprintf(tex2,"%sGraph\\Obj3D\\Interactive\\Items\\Armor\\Helmet_plate_cm\\Helmet_plate_cm.teo",Project.workingdir); break; case 1: sprintf(tex2,"%sGraph\\Obj3D\\Interactive\\Items\\Armor\\Legging_plate_cm\\Legging_plate_cm.teo",Project.workingdir); break; case 2: sprintf(tex2,"%sGraph\\Obj3D\\Interactive\\Items\\Armor\\Chest_plate_cm\\Chest_plate_cm.teo",Project.workingdir); break; default: return; break; } File_Standardize(tex2,tex); INTERACTIVE_OBJ * ioo=(INTERACTIVE_OBJ *)AddItem(GDevice,tex,IO_IMMEDIATELOAD); if (ioo!=NULL) { sp_wep=1; MakeCoolFx(&player.pos); MakeCoolFx(&player.pos); ioo->scriptload=1; MakeTemporaryIOIdent(ioo); SendInitScriptEvent(ioo); ioo->show=SHOW_FLAG_IN_INVENTORY; if (!CanBePutInInventory(ioo)) { PutInFrontOfPlayer(ioo,1); } MakeSpCol(); strcpy(sp_max_ch,"!! Toi aussi cherches les Cheats !!"); switch (sp_arm) { case 0: strcpy(sp_max_ch,"------ZoliChapo------"); break; case 1: strcpy(sp_max_ch,"-----TiteBottine-----"); break; case 2: strcpy(sp_max_ch,"-----Roooo-La-La-----"); break; default: return; break; } sp_max_nb=strlen(sp_max_ch); sp_max_start=ARX_TIME_Get(); } sp_arm++; } extern long SPECIAL_PNUX; void ApplyCurPNux() { { MakeSpCol(); strcpy(sp_max_ch,"! PhilNux & Gluonne !"); sp_max_nb=strlen(sp_max_ch); if (SPECIAL_PNUX<3) { SPECIAL_PNUX++; } else { SPECIAL_PNUX=0; } D3DTextr_InvalidateAllTextures(); D3DTextr_RestoreAllTextures(GDevice); ARX_PLAYER_Restore_Skin(); cur_pnux=0; sp_max_start=ARX_TIME_Get(); } } void ApplyPasswall() { MakeSpCol(); strcpy(sp_max_ch,"!!! PassWall !!!"); sp_max_nb=strlen(sp_max_ch); sp_max_start=ARX_TIME_Get(); if (USE_PLAYERCOLLISIONS) USE_PLAYERCOLLISIONS=0; else USE_PLAYERCOLLISIONS=1; } void ApplySPRf() { if (cur_rf==3) { MakeSpCol(); strcpy(sp_max_ch,"!!! RaFMode !!!"); sp_max_nb=strlen(sp_max_ch); sp_max_start=ARX_TIME_Get(); } } void ApplyCurMr() { if (cur_mr==3) { MakeSpCol(); strcpy(sp_max_ch,"!!! Marianna !!!"); sp_max_nb=strlen(sp_max_ch); sp_max_start=ARX_TIME_Get(); } } void ApplySPuw() { uw_mode_pos=0; uw_mode=~uw_mode; ARX_SOUND_PlayCinematic("menestrel_uw2.wav"); MakeCoolFx(&player.pos); if (uw_mode) { MakeSpCol(); strcpy(sp_max_ch,"~-__-~~-__.U.W.__-~~-__-~"); sp_max_nb=strlen(sp_max_ch); sp_max_start=ARX_TIME_Get(); } } void ApplySPMax() { MakeCoolFx(&player.pos); sp_max=~sp_max; if (sp_max) { MakeSpCol(); strcpy(sp_max_ch,"!!!_FaNt0mAc1e_!!!"); sp_max_nb=strlen(sp_max_ch); sp_max_start=ARX_TIME_Get(); player.skin=4; ARX_EQUIPMENT_RecreatePlayerMesh(); ARX_PLAYER_Rune_Add_All(); _TCHAR UText[512]; MultiByteToWideChar(CP_ACP, 0, "!!!!!!! FanTomAciE !!!!!!!", -1, UText, 256); ARX_SPEECH_Add(NULL, UText); player.Attribute_Redistribute+=10; player.Skill_Redistribute+=50; player.level=__max(player.level,10); player.xp=GetXPforLevel(10); } else { TextureContainer * tcm=MakeTCFromFile("Graph\\Obj3D\\Textures\\npc_human_cm_hero_head.bmp"); if (tcm) { D3DTextr_KillTexture(tcm); player.heads[0]=MakeTCFromFile("Graph\\Obj3D\\Textures\\npc_human_base_hero_head.bmp"); player.heads[1]=MakeTCFromFile("Graph\\Obj3D\\Textures\\npc_human_base_hero2_head.bmp"); player.heads[2]=MakeTCFromFile("Graph\\Obj3D\\Textures\\npc_human_base_hero3_head.bmp"); ARX_EQUIPMENT_RecreatePlayerMesh(); } } }