From: <ave...@us...> - 2007-05-01 10:37:42
|
Revision: 4628 http://gemrb.svn.sourceforge.net/gemrb/?rev=4628&view=rev Author: avenger_teambg Date: 2007-05-01 03:37:40 -0700 (Tue, 01 May 2007) Log Message: ----------- fixed MoveToObject lockup (hopefully) fixed OpenDoor lockup (impeded blocks shouldn't disable opening only closing) consolidated RemoveSpell code in spellbook Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Actions.cpp gemrb/trunk/gemrb/plugins/Core/Actor.cpp gemrb/trunk/gemrb/plugins/Core/ActorBlock.cpp gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp gemrb/trunk/gemrb/plugins/Core/Map.cpp gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp gemrb/trunk/gemrb/plugins/Core/Spellbook.h gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp Modified: gemrb/trunk/gemrb/plugins/Core/Actions.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-04-30 21:43:16 UTC (rev 4627) +++ gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-05-01 10:37:40 UTC (rev 4628) @@ -4280,11 +4280,9 @@ } Actor *actor = (Actor *) Sender; if (parameters->string0Parameter[0]) { - //actor->spellbook.HaveSpell(parameters->string0Parameter, HS_DEPLETE); actor->spellbook.RemoveSpell(parameters->string0Parameter); return; } - actor->spellbook.HaveSpell(parameters->int0Parameter, HS_DEPLETE); actor->spellbook.RemoveSpell(parameters->int0Parameter); } Modified: gemrb/trunk/gemrb/plugins/Core/Actor.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-04-30 21:43:16 UTC (rev 4627) +++ gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-05-01 10:37:40 UTC (rev 4628) @@ -692,7 +692,7 @@ 5,5,5,5,5,5,5,100,100,100,255,5,5,255,1,1,//8f 1,25,25,30,1,1,1,25,-1,100,100,1,255,255,255,255,//9f 255,255,255,255,255,255,20,255,255,1,20,255,999999999,999999999,1,1,//af -999999999,999999999,0,0,0,0,0,0,0,0,0,0,0,0,0,0,//bf +999999999,999999999,0,0,10,0,0,0,0,0,0,0,0,0,0,0,//bf 0,0,0,0,0,0,0,25,25,255,255,255,255,65535,-1,-1,//cf - 207 -1,-1,-1,-1,-1,-1,-1,-1,MAX_LEVEL,255,65535,3,255,255,255,255,//df - 223 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,//ef - 239 @@ -1014,7 +1014,15 @@ } ieDword diff = Modified[StatIndex]-BaseStats[StatIndex]; + //maximize the base stat + if ( maximum_values[StatIndex]>0) { + if ( (signed) Value>maximum_values[StatIndex]) { + Value = (ieDword) maximum_values[StatIndex]; + } + } + BaseStats[StatIndex] = Value; + //if already initialized, then the modified stats //need to run the post change function (stat change can kill actor) SetStat (StatIndex, Value+diff, InternalFlags&IF_INITIALIZED); @@ -1131,7 +1139,14 @@ } bonus *= GetXPLevel( true ); - NewBase(IE_MORALE,1,MOD_ADDITIVE); + //morale recovery every xth AI cycle + int mrec = GetStat(IE_MORALERECOVERYTIME); + if (mrec) { + if (!(core->GetGame()->GameTime%mrec)) { + NewBase(IE_MORALE,1,MOD_ADDITIVE); + } + } + if (bonus<0 && (Modified[IE_MAXHITPOINTS]+bonus)<=0) { bonus=1-Modified[IE_MAXHITPOINTS]; } @@ -1333,7 +1348,6 @@ //recalculate damage based on resistances and difficulty level //the lower 2 bits are actually modifier types NewBase(IE_HITPOINTS, (ieDword) -damage, damagetype&3); - NewBase(IE_MORALE, (ieDword) -1, MOD_ADDITIVE); //this is just a guess, probably morale is much more complex //add lastdamagetype up LastDamageType|=damagetype; @@ -1347,6 +1361,7 @@ } else if (damage<10) { damagelevel = 2; } else { + NewBase(IE_MORALE, (ieDword) -1, MOD_ADDITIVE); if (chp<-10) { damagelevel = 0; //chunky death } @@ -1506,7 +1521,7 @@ InternalFlags&=IF_FROMGAME; //keep these flags (what about IF_INITIALIZED) InternalFlags|=IF_ACTIVE|IF_VISIBLE; //set these flags SetBase(IE_STATE_ID, 0); - SetBase(IE_MORALE, 20); + SetBase(IE_MORALE, 10); SetBase(IE_HITPOINTS, BaseStats[IE_MAXHITPOINTS]); ClearActions(); ClearPath(); Modified: gemrb/trunk/gemrb/plugins/Core/ActorBlock.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/ActorBlock.cpp 2007-04-30 21:43:16 UTC (rev 4627) +++ gemrb/trunk/gemrb/plugins/Core/ActorBlock.cpp 2007-05-01 10:37:40 UTC (rev 4628) @@ -573,7 +573,6 @@ return; } } - LastTarget = 0; LastTargetPos = target; SpellCast(SpellResRef); } @@ -1309,7 +1308,11 @@ void Door::SetDoorOpen(bool Open, bool playsound, ieDword ID) { if (playsound) { - if (BlockedOpen(Open,0)) { + //the door cannot be blocked when opening, + //but the actors will be pushed + //BlockedOpen will mark actors to be pushed + if (BlockedOpen(Open,0) && !Open) { + //clear up the blocking actors area->JumpActors(false); return; } Modified: gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp 2007-04-30 21:43:16 UTC (rev 4627) +++ gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp 2007-05-01 10:37:40 UTC (rev 4628) @@ -1051,6 +1051,13 @@ } } actor->WalkTo( target->Pos, flags, 0 ); + Point dest = actor->Destination; + //hopefully this hack will prevent lockups + if (!actor->InMove()) { + Sender->ReleaseCurrentAction(); + return; + } + //repeat movement... Action *newaction = ParamCopyNoOverride(parameters); if (newaction->int0Parameter!=1) { Modified: gemrb/trunk/gemrb/plugins/Core/Map.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Map.cpp 2007-04-30 21:43:16 UTC (rev 4627) +++ gemrb/trunk/gemrb/plugins/Core/Map.cpp 2007-05-01 10:37:40 UTC (rev 4628) @@ -1367,6 +1367,7 @@ { int ret = SearchMap->GetPixelIndex( x, y ); if (ret&(PATH_MAP_DOOR_TRANSPARENT|PATH_MAP_ACTOR)) { +// if (ret&PATH_MAP_DOOR_TRANSPARENT) { ret&=~PATH_MAP_PASSABLE; } if (ret&PATH_MAP_DOOR_OPAQUE) { Modified: gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp 2007-04-30 21:43:16 UTC (rev 4627) +++ gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp 2007-05-01 10:37:40 UTC (rev 4628) @@ -260,6 +260,49 @@ return (unsigned int) spells[type][level]->known_spells.size(); } +//called when a spell was removed from spellbook +//this one purges all instances of known spells of the same name from memory +void Spellbook::RemoveMemorization(CRESpellMemorization* sm, ieResRef ResRef) +{ + std::vector< CREMemorizedSpell* >::iterator ms; + + for (ms = sm->memorized_spells.begin(); ms != sm->memorized_spells.end(); ms++) { + if (strnicmp(ResRef, (*ms)->SpellResRef, sizeof(ieResRef) ) ) { + continue; + } +printf("Removing %s\n", (*ms)->SpellResRef); + delete *ms; + sm->memorized_spells.erase(ms); + ms--; + } +} + +//removes one instance of spell (from creknownspell) +bool Spellbook::RemoveSpell(CREKnownSpell* spell) +{ + for (int i = 0; i < NUM_SPELL_TYPES; i++) { + std::vector< CRESpellMemorization* >::iterator sm; + for (sm = spells[i].begin(); sm != spells[i].end(); sm++) { + std::vector< CREKnownSpell* >::iterator ks; + for (ks = (*sm)->known_spells.begin(); ks != (*sm)->known_spells.end(); ks++) { + if (*ks == spell) { + ieResRef ResRef; + + memcpy(ResRef, (*ks)->SpellResRef, sizeof(ieResRef) ); + delete *ks; + (*sm)->known_spells.erase(ks); + RemoveMemorization(*sm, ResRef); + ClearSpellInfo(); + return true; + } + } + } + } + return false; +} + + +//removes all instances of spellid (probably not needed) void Spellbook::RemoveSpell(int spellid) { int type = spellid/1000; @@ -274,21 +317,15 @@ for (ks = (*sm)->known_spells.begin(); ks != (*sm)->known_spells.end(); ks++) { if (atoi((*ks)->SpellResRef+4)==spellid) { + ieResRef ResRef; + + memcpy(ResRef, (*ks)->SpellResRef, sizeof(ieResRef) ); delete *ks; (*sm)->known_spells.erase(ks); + RemoveMemorization(*sm, ResRef); ks--; } } - - std::vector< CREMemorizedSpell* >::iterator ms; - - for (ms = (*sm)->memorized_spells.begin(); ms != (*sm)->memorized_spells.end(); ms++) { - if (atoi((*ms)->SpellResRef+4)==spellid) { - delete *ms; - (*sm)->memorized_spells.erase(ms); - ms--; - } - } } } @@ -306,19 +343,9 @@ } delete *ks; (*sm)->known_spells.erase(ks); + RemoveMemorization(*sm, ResRef); ks--; } - - std::vector< CREMemorizedSpell* >::iterator ms; - - for (ms = (*sm)->memorized_spells.begin(); ms != (*sm)->memorized_spells.end(); ms++) { - if (strnicmp(ResRef, (*ms)->SpellResRef, sizeof(ResRef) ) ) { - continue; - } - delete *ms; - (*sm)->memorized_spells.erase(ms); - ms--; - } } } } Modified: gemrb/trunk/gemrb/plugins/Core/Spellbook.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spellbook.h 2007-04-30 21:43:16 UTC (rev 4627) +++ gemrb/trunk/gemrb/plugins/Core/Spellbook.h 2007-05-01 10:37:40 UTC (rev 4628) @@ -149,6 +149,8 @@ void ClearSpellInfo(); /** looks up the spellinfo list for an element */ SpellExtHeader *FindSpellInfo(unsigned int level, unsigned int type, ieResRef name); + /** removes all instances of a spell from a given page */ + void RemoveMemorization(CRESpellMemorization* sm, ieResRef ResRef); public: Spellbook(); ~Spellbook(); @@ -169,7 +171,10 @@ unsigned int GetTotalMemorizedSpellsCount() const; unsigned int GetKnownSpellsCount(int type, unsigned int level) const; /** removes a spell from memory/book */ + bool RemoveSpell(CREKnownSpell* spell); + /** this removes ALL spells of name ResRef */ void RemoveSpell(ieResRef ResRef); + /** this removes ALL spells matching spellid */ void RemoveSpell(int spellid); /** adds a spell to the book */ Modified: gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-04-30 21:43:16 UTC (rev 4627) +++ gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-05-01 10:37:40 UTC (rev 4628) @@ -5759,7 +5759,34 @@ return PyInt_FromLong( actor->LearnSpell(Spell, Flags) ); } +PyDoc_STRVAR( GemRB_RemoveSpell__doc, +"RemoveSpell(PartyID, SpellType, Level, Index)=>bool\n\n" +"Removes specified known spell. Returns 1 on success." ); +static PyObject* GemRB_RemoveSpell(PyObject * /*self*/, PyObject* args) +{ + int PartyID, SpellType, Level, Index; + + if (!PyArg_ParseTuple( args, "iiii", &PartyID, &SpellType, &Level, &Index )) { + return AttributeError( GemRB_RemoveSpell__doc ); + } + Game *game = core->GetGame(); + if (!game) { + return RuntimeError( "No game loaded!" ); + } + Actor* actor = game->FindPC( PartyID ); + if (!actor) { + return RuntimeError( "Actor not found" ); + } + + CREKnownSpell* ks = actor->spellbook.GetKnownSpell( SpellType, Level, Index ); + if (! ks) { + return NULL; + } + + return PyInt_FromLong( actor->spellbook.RemoveSpell( ks ) ); +} + PyDoc_STRVAR( GemRB_MemorizeSpell__doc, "MemorizeSpell(PartyID, SpellType, Level, Index)=>bool\n\n" "Memorizes specified known spell. Returns 1 on success." ); @@ -7981,6 +8008,7 @@ METHOD(GetMemorizedSpell, METH_VARARGS), METHOD(GetSpell, METH_VARARGS), METHOD(LearnSpell, METH_VARARGS), + METHOD(RemoveSpell, METH_VARARGS), METHOD(MemorizeSpell, METH_VARARGS), METHOD(UnmemorizeSpell, METH_VARARGS), METHOD(GetSlotItem, METH_VARARGS), This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |