Update of /cvsroot/gemrb/gemrb/gemrb/plugins/Core In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29459/plugins/Core Modified Files: Actions.cpp Actor.cpp Actor.h ActorBlock.cpp ActorBlock.h Effect.h EffectQueue.cpp GSUtils.cpp GSUtils.h Game.cpp Game.h GameScript.cpp GameScript.h GlobalTimer.cpp Interface.cpp Interface.h Spell.cpp Spell.h Spellbook.cpp Triggers.cpp Log Message: Implemented part of the spell system: ApplySpell action, *RES resolution Added some time related actions: AdvanceTimer, DayNight, etc Added some rest related actions: Rest, RestParty, etc GlobalTimer now increases gametime/realtime Index: Actor.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Actor.cpp,v retrieving revision 1.117 retrieving revision 1.118 diff -C2 -d -r1.117 -r1.118 *** Actor.cpp 16 Jul 2005 23:27:11 -0000 1.117 --- Actor.cpp 17 Jul 2005 18:58:24 -0000 1.118 *************** *** 354,358 **** void pcf_color(Actor *actor, ieDword /*Value*/) { ! actor->GetAnims()->SetColors(actor->Modified+IE_COLORS); } --- 354,361 ---- void pcf_color(Actor *actor, ieDword /*Value*/) { ! CharAnimations *anims = actor->GetAnims(); ! if (anims) { ! anims->SetColors(actor->Modified+IE_COLORS); ! } } *************** *** 464,471 **** return true; } ! /** call this after load, before applying effects */ void Actor::Init() { memcpy( Modified, BaseStats, MAX_STATS * sizeof( *Modified ) ); } /** implements a generic opcode function, modify modifier --- 467,475 ---- return true; } ! /** call this after load, to apply effects */ void Actor::Init() { memcpy( Modified, BaseStats, MAX_STATS * sizeof( *Modified ) ); + fxqueue.ApplyAllEffects( this ); } /** implements a generic opcode function, modify modifier *************** *** 639,643 **** core->GetGame()->SelectActor(this, false, SELECT_NORMAL); ClearPath(); ! InternalFlags|=IF_JUSTDIED; if (!InParty) { Actor *act=NULL; --- 643,647 ---- core->GetGame()->SelectActor(this, false, SELECT_NORMAL); ClearPath(); ! SetModal( 0 ); if (!InParty) { Actor *act=NULL; *************** *** 655,659 **** } ! InternalFlags|=IF_REALLYDIED; SetStance( IE_ANI_DIE ); } --- 659,665 ---- } ! //JUSTDIED will be removed when the Die() trigger executed ! //otherwise it is the same as REALLYDIED ! InternalFlags|=IF_REALLYDIED|IF_JUSTDIED; SetStance( IE_ANI_DIE ); } *************** *** 918,922 **** } ! anims->SetColors(Modified+IE_COLORS); } --- 924,930 ---- } ! if (anims) { ! anims->SetColors(Modified+IE_COLORS); ! } } *************** *** 928,929 **** --- 936,950 ---- } + //if days == 0, it means full healing + void Actor::Heal(int days) + { + if (days) { + NewStat(IE_HITPOINTS, days * 2, MOD_ADDITIVE); + } else { + SetStat(IE_HITPOINTS, GetStat(IE_MAXHITPOINTS)); + } + } + + void Actor::RemoveTimedEffects() + { + } Index: GlobalTimer.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/GlobalTimer.cpp,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** GlobalTimer.cpp 6 Jul 2005 23:37:34 -0000 1.21 --- GlobalTimer.cpp 17 Jul 2005 18:58:25 -0000 1.22 *************** *** 64,79 **** } GameControl* gc = core->GetGameControl(); ! if (gc) { ! if (gc->GetDialogueFlags()&DF_IN_DIALOG) ! return; } Game* game = core->GetGame(); ! if (game) { ! Map* map = game->GetCurrentArea(); ! if (map) { ! map->UpdateFog(); ! map->UpdateEffects(); ! } } if (CutScene) { if (CutScene->endReached) { --- 64,89 ---- } GameControl* gc = core->GetGameControl(); ! if (!gc) { ! return; } Game* game = core->GetGame(); ! if (!game) { ! return; } + Map* map = game->GetCurrentArea(); + if (!map) { + return; + } + //do spell effects expire in dialogs? + //if yes, then we should remove this condition + if (!(gc->GetDialogueFlags()&DF_IN_DIALOG) ) { + map->UpdateFog(); + map->UpdateEffects(); + //this measures in-world time (affected by effects, actions, etc) + game->AdvanceTime(1); + } + //this measures time spent in the game (including pauses) + game->RealTime++; + if (CutScene) { if (CutScene->endReached) { *************** *** 84,88 **** return; } - //Call Scripts Update } } --- 94,97 ---- Index: Spell.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Spell.h,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** Spell.h 3 Mar 2005 22:33:12 -0000 1.10 --- Spell.h 17 Jul 2005 18:58:26 -0000 1.11 *************** *** 28,31 **** --- 28,32 ---- #include "AnimationMgr.h" #include "Effect.h" + #include "EffectQueue.h" #ifdef WIN32 *************** *** 41,47 **** #endif ! // FIXME: drop SPLFeature completely and just use Effect ! typedef Effect SPLFeature; class GEM_EXPORT SPLExtHeader { --- 42,55 ---- #endif ! //values for Spell usability Flags + #define SF_HOSTILE 0x4 + #define SF_NO_LOS 0x8 + #define SF_NOT_INDOORS 0x20 + #define SF_HLA 0x40 + #define SF_TRIGGER 0x80 + //this is a relocated bit (used in iwd2 as 0x40) + #define SF_NOT_IN_COMBAT 0x100 + #define SF_SIMPLIFIED_DURATION 0x400 class GEM_EXPORT SPLExtHeader { *************** *** 68,72 **** ieWord ChargeDepletion; ieWord Projectile; ! SPLFeature* features; }; --- 76,80 ---- ieWord ChargeDepletion; ieWord Projectile; ! Effect* features; }; *************** *** 78,82 **** SPLExtHeader *ext_headers; ! SPLFeature* casting_features; ieStrRef SpellName; --- 86,91 ---- SPLExtHeader *ext_headers; ! Effect* casting_features; ! ieResRef Name; //the resref of the spell itself! ieStrRef SpellName; *************** *** 116,119 **** --- 125,132 ---- // AnimationMgr* SpellIconBAM; + public: + //-1 will return the cfb + EffectQueue *GetEffectQueue(int index); + EffectQueue *GetEffectBlock(int wanted_level); }; Index: ActorBlock.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/ActorBlock.cpp,v retrieving revision 1.101 retrieving revision 1.102 diff -C2 -d -r1.101 -r1.102 *** ActorBlock.cpp 16 Jul 2005 21:03:46 -0000 1.101 --- ActorBlock.cpp 17 Jul 2005 18:58:24 -0000 1.102 *************** *** 256,259 **** --- 256,260 ---- { tolist.clear(); + bittriggers = 0; } *************** *** 263,267 **** --- 264,275 ---- *(*m) = 0; } + if (bittriggers & BT_DIE) { + ((Actor *) this)->InternalFlags&=~IF_JUSTDIED; + } + } + void Scriptable::SetBitTrigger(ieDword bittrigger) + { + bittriggers |= bittrigger; } *************** *** 820,824 **** if (!actor->InParty && (Flags&TRAVEL_NONPC) ) return CT_CANTMOVE; if (Flags&TRAVEL_PARTY) { ! if (core->HasFeature(GF_TEAM_MOVEMENT) || core->GetGame()->EveryoneNearPoint(actor->Area, actor->Pos, ENP_CANMOVE) ) { return CT_WHOLE; } --- 828,832 ---- if (!actor->InParty && (Flags&TRAVEL_NONPC) ) return CT_CANTMOVE; if (Flags&TRAVEL_PARTY) { ! if (core->HasFeature(GF_TEAM_MOVEMENT) || core->GetGame()->EveryoneNearPoint(actor->GetCurrentArea(), actor->Pos, ENP_CANMOVE) ) { return CT_WHOLE; } *************** *** 827,831 **** if(actor->IsSelected() ) { ! if(core->GetGame()->EveryoneNearPoint(actor->Area, actor->Pos, ENP_CANMOVE|ENP_ONLYSELECT) ) { return CT_MOVE_SELECTED; --- 835,839 ---- if(actor->IsSelected() ) { ! if(core->GetGame()->EveryoneNearPoint(actor->GetCurrentArea(), actor->Pos, ENP_CANMOVE|ENP_ONLYSELECT) ) { return CT_MOVE_SELECTED; Index: GameScript.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/GameScript.cpp,v retrieving revision 1.312 retrieving revision 1.313 diff -C2 -d -r1.312 -r1.313 *** GameScript.cpp 16 Jul 2005 21:03:46 -0000 1.312 --- GameScript.cpp 17 Jul 2005 18:58:24 -0000 1.313 *************** *** 313,321 **** {"addxpvar", GameScript::AddXP2DA, 0}, {"advancetime", GameScript::AdvanceTime, 0}, ! {"allowarearesting", GameScript::SetAreaRestFlag, 0}, {"ally", GameScript::Ally, 0}, {"ambientactivate", GameScript::AmbientActivate, 0}, {"applydamage", GameScript::ApplyDamage, 0}, {"applydamagepercent", GameScript::ApplyDamagePercent, 0}, {"attachtransitiontodoor", GameScript::AttachTransitionToDoor, 0}, {"attack", GameScript::Attack,AF_BLOCKING}, --- 313,323 ---- {"addxpvar", GameScript::AddXP2DA, 0}, {"advancetime", GameScript::AdvanceTime, 0}, ! {"allowarearesting", GameScript::SetAreaRestFlag, 0},//iwd2 {"ally", GameScript::Ally, 0}, {"ambientactivate", GameScript::AmbientActivate, 0}, {"applydamage", GameScript::ApplyDamage, 0}, {"applydamagepercent", GameScript::ApplyDamagePercent, 0}, + {"applyspell", GameScript::ApplySpell, 0}, + {"applyspellpoint", GameScript::ApplySpellPoint, 0}, //gemrb extension {"attachtransitiontodoor", GameScript::AttachTransitionToDoor, 0}, {"attack", GameScript::Attack,AF_BLOCKING}, *************** *** 368,371 **** --- 370,374 ---- {"cutsceneid", GameScript::CutSceneID,AF_INSTANT}, {"damage", GameScript::Damage, 0}, + {"daynight", GameScript::DayNight, 0}, {"deactivate", GameScript::Deactivate, 0}, {"debug", GameScript::Debug, 0}, *************** *** 513,518 **** {"moveviewpoint", GameScript::MoveViewPoint, 0}, {"nidspecial1", GameScript::NIDSpecial1,AF_BLOCKING},//we use this for dialogs, hack ! {"nidspecial2", GameScript::NIDSpecial2,AF_BLOCKING},//we use this for worldmap, another hack ! {"nidspecial3", GameScript::Attack,AF_BLOCKING}, //this hack is for attacking preset target {"noaction", GameScript::NoAction, 0}, {"opendoor", GameScript::OpenDoor,AF_BLOCKING}, --- 516,521 ---- {"moveviewpoint", GameScript::MoveViewPoint, 0}, {"nidspecial1", GameScript::NIDSpecial1,AF_BLOCKING},//we use this for dialogs, hack ! {"nidspecial2", GameScript::NIDSpecial2,AF_BLOCKING},//we use this for worldmap, another hack ! {"nidspecial3", GameScript::Attack,AF_BLOCKING}, //this hack is for attacking preset target {"noaction", GameScript::NoAction, 0}, {"opendoor", GameScript::OpenDoor,AF_BLOCKING}, *************** *** 668,672 **** {"takepartyitemrange", GameScript::TakePartyItemRange, 0}, {"teleportparty", GameScript::TeleportParty, 0}, ! {"textscreen", GameScript::TextScreen, 0}, {"tomsstringdisplayer", GameScript::DisplayMessage, 0}, {"triggeractivation", GameScript::TriggerActivation, 0}, --- 671,675 ---- {"takepartyitemrange", GameScript::TakePartyItemRange, 0}, {"teleportparty", GameScript::TeleportParty, 0}, ! {"textscreen", GameScript::TextScreen, AF_BLOCKING}, {"tomsstringdisplayer", GameScript::DisplayMessage, 0}, {"triggeractivation", GameScript::TriggerActivation, 0}, Index: ActorBlock.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/ActorBlock.h,v retrieving revision 1.82 retrieving revision 1.83 diff -C2 -d -r1.82 -r1.83 *** ActorBlock.h 16 Jul 2005 21:03:46 -0000 1.82 --- ActorBlock.h 17 Jul 2005 18:58:24 -0000 1.83 *************** *** 99,102 **** --- 99,105 ---- #define CT_MOVE_SELECTED 5 //all selected can move + //bits for binary trigger bitfield + #define BT_DIE 1 + #ifdef WIN32 *************** *** 125,128 **** --- 128,132 ---- private: TriggerObjects tolist; + ieDword bittriggers; unsigned long startTime; unsigned long interval; *************** *** 174,177 **** --- 178,182 ---- void InitTriggers(); void ClearTriggers(); + void SetBitTrigger(ieDword bittrigger); void AddTrigger(ieDword *actorref); }; Index: Game.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Game.h,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -d -r1.61 -r1.62 *** Game.h 17 Jul 2005 17:49:19 -0000 1.61 --- Game.h 17 Jul 2005 18:58:24 -0000 1.62 *************** *** 235,239 **** bool EveryoneStopped() const; bool EveryoneNearPoint(Map *map, Point &p, int flags) const; ! bool PartyMemberDied() const; /* increments chapter variable and refreshes kill stats */ void IncrementChapter(); --- 235,239 ---- bool EveryoneStopped() const; bool EveryoneNearPoint(Map *map, Point &p, int flags) const; ! int PartyMemberDied() const; /* increments chapter variable and refreshes kill stats */ void IncrementChapter(); Index: GSUtils.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/GSUtils.cpp,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** GSUtils.cpp 16 Jul 2005 21:03:46 -0000 1.13 --- GSUtils.cpp 17 Jul 2005 18:58:24 -0000 1.14 *************** *** 146,149 **** --- 146,171 ---- } + // SPIT is not in the original engine spec, it is reserved for the + // enchantable items feature + // 0 1 2 3 4 + static const char *spell_suffices[]={"SPIT","SPPR","SPWI","SPIN","SPCL"}; + + //this function handles the polymorphism of Spell[RES] actions + bool ResolveSpellName(ieResRef spellres, Action *parameters) + { + if (parameters->string0Parameter) { + strnuprcpy(spellres, parameters->string0Parameter, 8); + } else { + //resolve spell + int type = parameters->int0Parameter/1000; + int spellid = parameters->int0Parameter%1000; + if (type>4) { + return false; + } + sprintf(spellres, "%s%03d", spell_suffices[type], spellid); + } + return true; + } + void DisplayStringCore(Scriptable* Sender, int Strref, int flags) { *************** *** 725,729 **** } ! bool GameScript::MatchActor(Scriptable *Sender, ieDword actorID, Object* oC) { if (!Sender || !oC) { --- 747,751 ---- } ! bool MatchActor(Scriptable *Sender, ieDword actorID, Object* oC) { if (!Sender || !oC) { *************** *** 748,752 **** } ! int GameScript::GetObjectCount(Scriptable* Sender, Object* oC) { if (!oC) { --- 770,774 ---- } ! int GetObjectCount(Scriptable* Sender, Object* oC) { if (!oC) { Index: GSUtils.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/GSUtils.h,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** GSUtils.h 10 Jul 2005 12:01:48 -0000 1.6 --- GSUtils.h 17 Jul 2005 18:58:24 -0000 1.7 *************** *** 53,56 **** --- 53,57 ---- void InitScriptTables(); void HandleBitMod(ieDword &value1, ieDword value2, int opcode); + bool ResolveSpellName(ieResRef spellres, Action *parameter); void DisplayStringCore(Scriptable* Sender, int Strref, int flags); void EscapeAreaCore(Actor *src, const char *resref, Point &enter, Point &exit, int flags); *************** *** 61,64 **** --- 62,69 ---- Action *ParamCopy(Action *parameters); Action *ParamCopyNoOverride(Action *parameters); + /* returns true if actor matches the object specs. */ + bool MatchActor(Scriptable *Sender, ieDword ID, Object* oC); + /* returns the number of actors matching the IDS targeting */ + int GetObjectCount(Scriptable* Sender, Object* oC); void SetVariable(Scriptable* Sender, const char* VarName, const char* Context, ieDword value); void SetVariable(Scriptable* Sender, const char* VarName, ieDword value); Index: Spell.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Spell.cpp,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Spell.cpp 11 Jun 2005 20:18:01 -0000 1.8 --- Spell.cpp 17 Jul 2005 18:58:26 -0000 1.9 *************** *** 48,49 **** --- 48,89 ---- */ } + + //-1 will return cfb + //0 will always return first spell block + //otherwise set to caster level + EffectQueue *Spell::GetEffectBlock(int level) + { + Effect *features; + int count; + + //iwd2 has this hack + if (level>=0) { + if (Flags & SF_SIMPLIFIED_DURATION) { + features = ext_headers[0].features; + count = ext_headers[0].FeatureCount; + } else { + int block_index; + for(block_index=0;block_index<ExtHeaderCount-1;block_index++) { + if (ext_headers[block_index+1].RequiredLevel>level) { + break; + } + } + features = ext_headers[block_index].features; + count = ext_headers[block_index].FeatureCount; + } + } else { + features = casting_features; + count = CastingFeatureCount; + } + EffectQueue *fxqueue = new EffectQueue(); + + for (int i=0;i<count;i++) { + if (Flags & SF_SIMPLIFIED_DURATION) { + //hack the effect according to Level + //fxqueue->AddEffect will copy the effect, + //so we don't risk any overwriting + } + fxqueue->AddEffect( features+i ); + } + return fxqueue; + } Index: Effect.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Effect.h,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Effect.h 12 Jul 2005 18:11:16 -0000 1.5 --- Effect.h 17 Jul 2005 18:58:24 -0000 1.6 *************** *** 64,69 **** ieDword Parameter1; ieDword Parameter2; ! ieByte TimingMode; ! ieByte Resistance; ieDword Duration; ieWord Probability1; --- 64,69 ---- ieDword Parameter1; ieDword Parameter2; ! ieDword TimingMode; ! ieDword Resistance; ieDword Duration; ieWord Probability1; *************** *** 83,87 **** // EFF V2.0 fields: ieDword PrimaryType; - ieDword ResistanceType; ieDword Parameter3; ieDword Parameter4; --- 83,86 ---- Index: GameScript.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/GameScript.h,v retrieving revision 1.210 retrieving revision 1.211 diff -C2 -d -r1.210 -r1.211 *** GameScript.h 16 Jul 2005 21:03:46 -0000 1.210 --- GameScript.h 17 Jul 2005 18:58:25 -0000 1.211 *************** *** 650,656 **** private: /* returns true if actor matches the object specs. */ ! static bool MatchActor(Scriptable *Sender, ieDword ID, Object* oC); /* returns the number of actors matching the IDS targeting */ ! static int GetObjectCount(Scriptable* Sender, Object* oC); static Targets *XthNearestOf(Targets *parameters, int count); --- 650,656 ---- private: /* returns true if actor matches the object specs. */ ! //static bool MatchActor(Scriptable *Sender, ieDword ID, Object* oC); /* returns the number of actors matching the IDS targeting */ ! //static int GetObjectCount(Scriptable* Sender, Object* oC); static Targets *XthNearestOf(Targets *parameters, int count); *************** *** 949,952 **** --- 949,954 ---- static void ApplyDamage(Scriptable* Sender, Action* parameters); static void ApplyDamagePercent(Scriptable* Sender, Action* parameters); + static void ApplySpell(Scriptable* Sender, Action* parameters); + static void ApplySpellPoint(Scriptable* Sender, Action* parameters); static void AttachTransitionToDoor(Scriptable* Sender, Action* parameters); static void Attack(Scriptable* Sender, Action* parameters); *************** *** 973,976 **** --- 975,979 ---- static void ClearActions(Scriptable* Sender, Action* parameters); static void ClearAllActions(Scriptable* Sender, Action* parameters); + static void ClearPartyEffects(Scriptable* Sender, Action* parameters); static void CloseDoor(Scriptable* Sender, Action* parameters); static void ContainerEnable(Scriptable* Sender, Action* parameters); *************** *** 994,997 **** --- 997,1001 ---- static void CutSceneID(Scriptable* Sender, Action* parameters); static void Damage(Scriptable* Sender, Action* parameters); + static void DayNight(Scriptable *Sender, Action* parameters); static void Deactivate(Scriptable* Sender, Action* parameters); static void Debug(Scriptable* Sender, Action* parameters); *************** *** 1164,1167 **** --- 1168,1175 ---- static void ReputationSet(Scriptable* Sender, Action* parameters); static void RestorePartyLocation(Scriptable *Sender, Action* parameters); + static void Rest(Scriptable *Sender, Action* parameters); + static void RestNoSpells(Scriptable *Sender, Action* parameters); + static void RestParty(Scriptable *Sender, Action* parameters); + static void RestUntilHealed(Scriptable *Sender, Action* parameters); static void RevealAreaOnMap(Scriptable* Sender, Action* parameters); static void RunAwayFrom(Scriptable* Sender, Action* parameters); Index: Interface.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Interface.h,v retrieving revision 1.165 retrieving revision 1.166 diff -C2 -d -r1.165 -r1.166 *** Interface.h 16 Jul 2005 21:03:46 -0000 1.165 --- Interface.h 17 Jul 2005 18:58:26 -0000 1.166 *************** *** 119,122 **** --- 119,123 ---- Cache ItemCache; Cache SpellCache; + Cache EffectCache; Factory * factory; ImageMgr * pal256; *************** *** 403,406 **** --- 404,409 ---- Spell* GetSpell(const ieResRef resname); void FreeSpell(Spell *spl, const ieResRef name, bool free=false); + Effect* GetEffect(const ieResRef resname); + void FreeEffect(Effect *eff, const ieResRef name, bool free=false); ieStrRef GetRumour(const ieResRef resname); Container *GetCurrentContainer(); *************** *** 435,438 **** --- 438,449 ---- returns gold value! */ int CanMoveItem(CREItem *item); + + /** applies the spell on the target */ + void ApplySpell(const ieResRef resname, Actor *target, Actor *caster, int level); + /** applies the spell on the area or on a scriptable object */ + void ApplySpellPoint(const ieResRef resname, Scriptable *target, Point &pos, Actor *caster, int level); + /** applies a single effect on the target */ + void ApplyEffect(const ieResRef resname, Actor *target, Actor *caster, int level); + /** dumps an area object to the cache */ int SwapoutArea(Map *map); Index: Triggers.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Triggers.cpp,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** Triggers.cpp 16 Jul 2005 21:03:47 -0000 1.15 --- Triggers.cpp 17 Jul 2005 18:58:26 -0000 1.16 *************** *** 1185,1188 **** --- 1185,1190 ---- Actor *act=(Actor *) Sender; if (act->InternalFlags&IF_JUSTDIED) { + //set trigger to erase + act->SetBitTrigger(BT_DIE); return 1; } *************** *** 1192,1196 **** int GameScript::PartyMemberDied(Scriptable* /*Sender*/, Trigger* /*parameters*/) { ! return core->GetGame()->PartyMemberDied(); } --- 1194,1205 ---- int GameScript::PartyMemberDied(Scriptable* /*Sender*/, Trigger* /*parameters*/) { ! Game *game = core->GetGame(); ! int i = game->PartyMemberDied(); ! if (i==-1) { ! return 0; ! } ! //set trigger to erase ! game->GetPC(i,false)->SetBitTrigger(BT_DIE); ! return 1; } *************** *** 1199,1202 **** --- 1208,1213 ---- Actor* actor = core->GetGame()->FindPC(1); if (actor->InternalFlags&IF_JUSTDIED) { + //set trigger to clear + actor->SetBitTrigger(BT_DIE); return 1; } Index: Game.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Game.cpp,v retrieving revision 1.87 retrieving revision 1.88 diff -C2 -d -r1.87 -r1.88 *** Game.cpp 17 Jul 2005 17:49:20 -0000 1.87 --- Game.cpp 17 Jul 2005 18:58:24 -0000 1.88 *************** *** 732,742 **** } ! bool Game::PartyMemberDied() const { for (unsigned int i=0; i<PCs.size(); i++) { ! if (PCs[i]->InternalFlags&IF_JUSTDIED) ! return true; } ! return false; } --- 732,743 ---- } ! int Game::PartyMemberDied() const { for (unsigned int i=0; i<PCs.size(); i++) { ! if (PCs[i]->InternalFlags&IF_JUSTDIED) { ! return i; ! } } ! return -1; } Index: Actor.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Actor.h,v retrieving revision 1.78 retrieving revision 1.79 diff -C2 -d -r1.78 -r1.79 *** Actor.h 16 Jul 2005 21:03:46 -0000 1.78 --- Actor.h 17 Jul 2005 18:58:24 -0000 1.79 *************** *** 302,305 **** --- 302,307 ---- void CreateStats(); int GetHPMod(); + /* Heals actor by days */ + void Heal(int days); /* Sets the modal state after checks */ void SetModal(ieDword newstate); *************** *** 310,313 **** --- 312,316 ---- /* sets a colour gradient stat, handles location */ void SetColor( ieDword idx, ieDword grd); + void RemoveTimedEffects(); }; #endif Index: Interface.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Interface.cpp,v retrieving revision 1.333 retrieving revision 1.334 diff -C2 -d -r1.333 -r1.334 *** Interface.cpp 16 Jul 2005 21:03:46 -0000 1.333 --- Interface.cpp 17 Jul 2005 18:58:25 -0000 1.334 *************** *** 44,47 **** --- 44,48 ---- #include "ItemMgr.h" #include "SpellMgr.h" + #include "EffectMgr.h" #include "StoreMgr.h" #include "DialogMgr.h" *************** *** 190,193 **** --- 191,199 ---- } + static void ReleaseEffect(void *poi) + { + delete ((Effect *) poi); + } + Interface::~Interface(void) { *************** *** 205,208 **** --- 211,215 ---- ItemCache.RemoveAll(ReleaseItem); SpellCache.RemoveAll(ReleaseSpell); + EffectCache.RemoveAll(ReleaseEffect); if (DefSound) { free( DefSound ); *************** *** 3184,3187 **** --- 3191,3197 ---- FreeInterface( sm ); + + //this is required for storing the 'source' + strnuprcpy(spell->Name, resname, 8); SpellCache.SetAt(resname, (void *) spell); return spell; *************** *** 3195,3199 **** if (res<0) { printMessage( "Core", "Corrupted Spell cache encountered (reference count went below zero), ", LIGHT_RED ); ! printf( "Spell name is: %.8s\n", name); abort(); } --- 3205,3209 ---- if (res<0) { printMessage( "Core", "Corrupted Spell cache encountered (reference count went below zero), ", LIGHT_RED ); ! printf( "Spell name is: %.8s or %.8s\n", name, spl->Name); abort(); } *************** *** 3202,3205 **** --- 3212,3259 ---- } + Effect* Interface::GetEffect(const ieResRef resname) + { + Effect *effect = (Effect *) EffectCache.GetResource(resname); + if (effect) { + return effect; + } + DataStream* str = key->GetResource( resname, IE_EFF_CLASS_ID ); + EffectMgr* em = ( EffectMgr* ) GetInterface( IE_EFF_CLASS_ID ); + if (em == NULL) { + delete ( str ); + return NULL; + } + if (!em->Open( str, true )) { + FreeInterface( em ); + return NULL; + } + + effect = em->GetEffect(new Effect() ); + if (effect == NULL) { + FreeInterface( em ); + return NULL; + } + + FreeInterface( em ); + + EffectCache.SetAt(resname, (void *) effect); + return effect; + } + + void Interface::FreeEffect(Effect *eff, const ieResRef name, bool free) + { + int res; + + res=EffectCache.DecRef((void *) eff, name, free); + if (res<0) { + printMessage( "Core", "Corrupted Effect cache encountered (reference count went below zero), ", LIGHT_RED ); + printf( "Effect name is: %.8s\n", name); + abort(); + } + if (res) return; + if (free) delete eff; + } + + //now that we store spell name in spl, i guess, we shouldn't pass 'ieResRef name' //these functions are needed because Win32 doesn't allow freeing memory from //another dll. So we allocate all commonly used memories from core *************** *** 3457,3460 **** --- 3511,3563 ---- } + // dealing with applying effects + void Interface::ApplySpell(const ieResRef resname, Actor *actor, Actor *caster, int level) + { + Spell *spell = GetSpell(resname); + if (!spell) { + return; + } + if (!level) { + level = 1; + } + EffectQueue *fxqueue = spell->GetEffectBlock(level); + fxqueue->SetOwner( caster ); + fxqueue->ApplyAllEffects(actor); + delete fxqueue; + } + + void Interface::ApplySpellPoint(const ieResRef resname, Scriptable* /*target*/, Point &/*pos*/, Actor *caster, int level) + { + Spell *spell = GetSpell(resname); + if (!spell) { + return; + } + if (!level) { + level = 1; + } + EffectQueue *fxqueue = spell->GetEffectBlock(level); + fxqueue->SetOwner( caster ); + //add effect to area??? + delete fxqueue; + } + + void Interface::ApplyEffect(const ieResRef resname, Actor *actor, Actor *caster, int level) + { + Effect *effect = GetEffect(resname); + if (!effect) { + return; + } + if (!level) { + level = 1; + } + EffectQueue *fxqueue = new EffectQueue(); + fxqueue->SetOwner( caster ); + fxqueue->AddEffect( effect ); + delete effect; + fxqueue->ApplyAllEffects( actor ); + delete fxqueue; + } + + // dealing with saved games int Interface::SwapoutArea(Map *map) { Index: EffectQueue.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/EffectQueue.cpp,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** EffectQueue.cpp 14 Jul 2005 22:19:44 -0000 1.23 --- EffectQueue.cpp 17 Jul 2005 18:58:24 -0000 1.24 *************** *** 249,252 **** --- 249,255 ---- void EffectQueue::ApplyEffect(Actor* target, Effect* fx) { + if (!target) { + return; + } //printf( "FX 0x%02x: %s(%d, %d)\n", fx->Opcode, effectnames[fx->Opcode].Name, fx->Parameter1, fx->Parameter2 ); if (fx->Opcode >= MAX_EFFECTS) *************** *** 261,265 **** EffectFunction fn = effect_refs[fx->Opcode].Function; if (fn) { ! if( fn( Owner, target, fx ) == FX_NOT_APPLIED) { //pending removal fx->TimingMode=FX_DURATION_JUST_EXPIRED; --- 264,269 ---- EffectFunction fn = effect_refs[fx->Opcode].Function; if (fn) { ! //if there is no owner, we assume it is the target ! if( fn( Owner?Owner:target, target, fx ) == FX_NOT_APPLIED) { //pending removal fx->TimingMode=FX_DURATION_JUST_EXPIRED; Index: Spellbook.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Spellbook.cpp,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** Spellbook.cpp 29 Jun 2005 17:59:24 -0000 1.26 --- Spellbook.cpp 17 Jul 2005 18:58:26 -0000 1.27 *************** *** 154,157 **** --- 154,160 ---- { int type = spellid/1000; + if (type>4) { + return false; + } type = sections[type]; spellid = spellid % 1000; Index: Actions.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Actions.cpp,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** Actions.cpp 16 Jul 2005 21:03:45 -0000 1.22 --- Actions.cpp 17 Jul 2005 18:58:24 -0000 1.23 *************** *** 1432,1436 **** } Actor *actor = (Actor *) Sender; ! if (!game->EveryoneNearPoint(actor->Area, actor->Pos, true) ) { //we abort the command, everyone should be here Sender->CurrentAction = NULL; --- 1432,1436 ---- } Actor *actor = (Actor *) Sender; ! if (!game->EveryoneNearPoint(actor->GetCurrentArea(), actor->Pos, true) ) { //we abort the command, everyone should be here Sender->CurrentAction = NULL; *************** *** 1712,1715 **** --- 1712,1721 ---- void GameScript::ForceSpell(Scriptable* Sender, Action* parameters) { + ieResRef spellres; + + if (!ResolveSpellName( spellres, parameters) ) { + return; + } + Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); if (!tar) { *************** *** 2794,2798 **** } Actor *scr = (Actor *) tar; ! scr->SetStat(IE_HITPOINTS, scr->GetStat(IE_MAXHITPOINTS) ); } --- 2800,2807 ---- } Actor *scr = (Actor *) tar; ! //0 means full healing ! //Heal() might contain curing of some conditions ! //if FullHeal doesn't do that, replace this with a setstat ! scr->Heal(0); } *************** *** 3581,3587 **** } ! void GameScript::AdvanceTime( Scriptable* /*Sender*/, Action* parameters) { ! core->GetGame()->GameTime += parameters->int0Parameter; } --- 3590,3693 ---- } ! //iwd2 ! //advance time with a constant ! void GameScript::AdvanceTime(Scriptable* /*Sender*/, Action* parameters) { ! core->GetGame()->AdvanceTime(parameters->int0Parameter); ! } ! ! //advance at least one day, then stop at next day/dusk/night/morning ! void GameScript::DayNight(Scriptable* /*Sender*/, Action* parameters) ! { ! int padding = core->GetGame()->GameTime%7200; ! padding = (padding/1800+4-parameters->int0Parameter)%4*1800; ! core->GetGame()->AdvanceTime(7200+padding); ! } ! ! //implement pst style parameters: ! //suggested dream, hp, renting? ! //if suggested dream is 0, then area flags determine the 'movie' ! void GameScript::RestParty(Scriptable* Sender, Action* parameters) ! { ! Game *game = core->GetGame(); ! ! if (!game->EveryoneStopped()) { ! // ! Sender->CurrentAction = NULL; ! return; ! } ! //there must be someone alive, or we'll have a crash ! Actor *leader = game->GetPC(0, true); ! if (!game->EveryoneNearPoint(leader->GetCurrentArea(), leader->Pos, 0)) { ! // ! Sender->CurrentAction = NULL; ! return; ! } ! ! game->AdvanceTime(7200); ! //HP set to 1 means HP will be recovered ! int i = game->GetPartySize(false); ! while (i--) { ! Actor *tar = game->GetPC(i, false); ! tar->ClearPath(); ! tar->ClearActions(); ! tar->SetModal(0); ! if (parameters->int1Parameter) { ! //renting could be 0,1,2,3 (the quality of resting) ! tar->Heal(parameters->int2Parameter+1); ! } ! tar->spellbook.ChargeAllSpells(); ! } ! Sender->CurrentAction = NULL; ! } ! ! //doesn't advance game time, just refreshes spells of target ! //this is a non-blocking action ! void GameScript::Rest(Scriptable* Sender, Action* /*parameters*/) ! { ! if (Sender->Type!=ST_ACTOR) { ! return; ! } ! Actor *actor = (Actor *) Sender; ! actor->spellbook.ChargeAllSpells(); ! //check if this should be a full heal ! actor->Heal(0); ! actor->RemoveTimedEffects(); ! } ! ! //doesn't advance game time (unsure), just refreshes spells of target ! void GameScript::RestNoSpells(Scriptable* Sender, Action* /*parameters*/) ! { ! if (Sender->Type!=ST_ACTOR) { ! return; ! } ! Actor *actor = (Actor *) Sender; ! //check if this should be a full heal ! actor->Heal(0); ! actor->RemoveTimedEffects(); ! } ! ! //this is most likely advances time ! void GameScript::RestUntilHealed(Scriptable* Sender, Action* /*parameters*/) ! { ! if (Sender->Type!=ST_ACTOR) { ! return; ! } ! Actor *actor = (Actor *) Sender; ! actor->Heal(1); ! //not sure if this should remove timed effects ! //more like execute them hour by hour :> ! } ! ! //iwd2 ! //removes all delayed/duration/semi permanent effects (like a ctrl-r) ! void GameScript::ClearPartyEffects(Scriptable* /*Sender*/, Action* /*parameters*/) ! { ! Game *game = core->GetGame(); ! int i = game->GetPartySize(false); ! while (i--) { ! Actor *tar = game->GetPC(i, false); ! tar->RemoveTimedEffects(); ! } } *************** *** 4060,4061 **** --- 4166,4220 ---- } + void GameScript::ApplySpell(Scriptable* Sender, Action* parameters) + { + ieResRef spellres; + + if (!ResolveSpellName( spellres, parameters) ) { + return; + } + + Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); + if (!tar) { + return; + } + if (tar->Type==ST_ACTOR) { + //apply spell on target + Actor *owner; + + if (Sender->Type==ST_ACTOR) { + owner = (Actor *) Sender; + } else { + owner = (Actor *) tar; + } + core->ApplySpell(spellres, (Actor *) tar, owner, parameters->int1Parameter); + } else { + //no idea about this one + Actor *owner; + + if (Sender->Type==ST_ACTOR) { + owner = (Actor *) Sender; + } else { + owner = NULL; + } + //apply spell on point + core->ApplySpellPoint(spellres, tar, tar->Pos, owner, parameters->int1Parameter); + } + } + + void GameScript::ApplySpellPoint(Scriptable* Sender, Action* parameters) + { + ieResRef spellres; + Actor *owner; + + if (!ResolveSpellName( spellres, parameters) ) { + return; + } + + if (Sender->Type==ST_ACTOR) { + owner = (Actor *) Sender; + } else { + owner = NULL; + } + Scriptable *tar = Sender->GetCurrentArea(); + core->ApplySpellPoint(spellres, tar, parameters->pointParameter, owner, parameters->int1Parameter); + } |