From: <ave...@us...> - 2007-02-28 19:01:36
|
Revision: 4509 http://gemrb.svn.sourceforge.net/gemrb/?rev=4509&view=rev Author: avenger_teambg Date: 2007-02-28 11:01:36 -0800 (Wed, 28 Feb 2007) Log Message: ----------- implemented SDLVideo::MouseClick Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/EventMgr.h gemrb/trunk/gemrb/plugins/Core/Video.h gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.cpp gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.h Modified: gemrb/trunk/gemrb/plugins/Core/EventMgr.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/EventMgr.h 2007-02-27 23:03:36 UTC (rev 4508) +++ gemrb/trunk/gemrb/plugins/Core/EventMgr.h 2007-02-28 19:01:36 UTC (rev 4509) @@ -54,6 +54,8 @@ // Mouse buttons #define GEM_MB_ACTION 1 #define GEM_MB_MENU 4 +//not working actually +#define GEM_MB_DOUBLECLICK 256 #ifdef WIN32 Modified: gemrb/trunk/gemrb/plugins/Core/Video.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Video.h 2007-02-27 23:03:36 UTC (rev 4508) +++ gemrb/trunk/gemrb/plugins/Core/Video.h 2007-02-28 19:01:36 UTC (rev 4509) @@ -168,8 +168,10 @@ /** Transforms sprite to have an alpha channel */ virtual void CreateAlpha(Sprite2D *sprite) = 0; - /** Convers a Screen Coordinate to a Game Coordinate */ + /** Converts a Screen Coordinate to a Game Coordinate */ virtual void ConvertToGame(short& x, short& y) = 0; + /** Converts a Game Coordinate to a Screen Coordinate */ + virtual void ConvertToScreen(short& x, short& y) = 0; /** Sets the Fading Color */ virtual void SetFadeColor(int r, int g, int b) = 0; /** Sets the Fading to Color Percentage */ @@ -180,6 +182,8 @@ virtual void GetClipRect(Region& clip) = 0; /** returns the current mouse coordinates */ virtual void GetMousePos(int &x, int &y) = 0; + /** clicks the mouse forcibly */ + virtual void ClickMouse(unsigned int button) = 0; /** moves the mouse forcibly */ virtual void MoveMouse(unsigned int x, unsigned int y) = 0; /** initializes the screen for movie */ Modified: gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.cpp 2007-02-27 23:03:36 UTC (rev 4508) +++ gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.cpp 2007-02-28 19:01:36 UTC (rev 4509) @@ -2250,6 +2250,27 @@ SDL_WarpMouse(x,y); } +void SDLVideoDriver::ClickMouse(unsigned int button) +{ + MouseClickEvent(SDL_MOUSEBUTTONDOWN, (Uint8) button); + MouseClickEvent(SDL_MOUSEBUTTONUP, (Uint8) button); + if (button&GEM_MB_DOUBLECLICK) { + MouseClickEvent(SDL_MOUSEBUTTONDOWN, (Uint8) button); + MouseClickEvent(SDL_MOUSEBUTTONUP, (Uint8) button); + } +} + +void SDLVideoDriver::MouseClickEvent(Uint8 type, Uint8 button) +{ + SDL_MouseButtonEvent *event = new SDL_MouseButtonEvent(); + event->type = type; + event->button = button; + event->state = (type==SDL_MOUSEBUTTONDOWN)?SDL_PRESSED:SDL_RELEASED; + event->x = CursorPos.x; + event->y = CursorPos.y; + SDL_PushEvent((SDL_Event *) event); +} + void SDLVideoDriver::InitMovieScreen(int &w, int &h) { SDL_LockSurface( disp ); Modified: gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.h =================================================================== --- gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.h 2007-02-27 23:03:36 UTC (rev 4508) +++ gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.h 2007-02-28 19:01:36 UTC (rev 4509) @@ -70,6 +70,8 @@ void GetMousePos(int &x, int &y); void MouseMovement(int x, int y); void MoveMouse(unsigned int x, unsigned int y); + void ClickMouse(unsigned int button); + void MouseClickEvent(Uint8 type, Uint8 button); Sprite2D* CreateSprite(int w, int h, int bpp, ieDword rMask, ieDword gMask, ieDword bMask, ieDword aMask, void* pixels, bool cK = false, int index = 0); @@ -139,6 +141,12 @@ y += Viewport.y; } + void ConvertToScreen(short&x, short& y) + { + x -= Viewport.x; + y -= Viewport.y; + } + void SetFadeColor(int r, int g, int b); void SetFadePercent(int percent); void InitMovieScreen(int &w, int &h); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-03-11 12:58:13
|
Revision: 4542 http://gemrb.svn.sourceforge.net/gemrb/?rev=4542&view=rev Author: avenger_teambg Date: 2007-03-11 05:58:14 -0700 (Sun, 11 Mar 2007) Log Message: ----------- displaying usage counts for weapons/quick items Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Item.cpp gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp Modified: gemrb/trunk/gemrb/plugins/Core/Item.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Item.cpp 2007-03-11 12:48:34 UTC (rev 4541) +++ gemrb/trunk/gemrb/plugins/Core/Item.cpp 2007-03-11 12:58:14 UTC (rev 4542) @@ -109,7 +109,7 @@ header = 0; } ccount = --Charges[header]; - if (!ieh->Charges) { + if (ieh->Charges==0) { return CHG_NONE; } if (ccount>0) { Modified: gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-03-11 12:48:34 UTC (rev 4541) +++ gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-03-11 12:58:14 UTC (rev 4542) @@ -4480,7 +4480,7 @@ } -Sprite2D* GetUsedWeaponIcon(Item *item, int which) +static Sprite2D* GetUsedWeaponIcon(Item *item, int which) { ITMExtHeader *ieh = item->GetWeaponHeader(false); if (!ieh) { @@ -4492,6 +4492,22 @@ return core->GetBAMSprite(item->ItemIcon, -1, which); } +static void SetItemText(int wi, int ci, int charges) +{ + Button* btn = (Button *) GetControl( wi, ci, IE_GUI_BUTTON ); + if (!btn) { + return; + } + char tmp[10]; + + if (charges) { + sprintf(tmp,"%d",charges); + } else { + tmp[0]=0; + } + btn->SetText(tmp); +} + PyDoc_STRVAR( GemRB_SetItemIcon__doc, "SetItemIcon(WindowIndex, ControlIndex, ITMResRef[, type, tooltip, Function, ITM2ResRef])\n\n" "Sets Item icon image on a button. 0/1 - Inventory Icons, 2 - Description Icon, 3 - No icon." ); @@ -6725,23 +6741,7 @@ } core->DelTable( table ); } -/* - table = core->LoadTable( "qslots"); - if (table<0) { - return; - } - tab = core->GetTable( table ); - ClassCount = tab->GetRowCount(); - GUIBTDefaults = new ActionButtonRow[ClassCount]; - for (i = 0; i < ClassCount; i++) { - memcpy(GUIBTDefaults+i, &DefaultButtons, sizeof(ActionButtonRow)); - for (int j=0;j<9;j++) { - GUIBTDefaults[i][j+3]=atoi( tab->QueryField(i,j) ); - } - } -} -*/ static void SetButtonCycle(AnimationFactory *bam, Button *btn, int cycle, unsigned char which) { Sprite2D *tspr = bam->GetFrame( cycle, 0 ); @@ -7195,6 +7195,7 @@ } } SetItemIcon(wi, ci, item->ItemResRef,mode,(item->Flags&IE_INV_ITEM_IDENTIFIED)?2:1, i+1, Item2ResRef); + SetItemText(wi, ci, item->Usages[actor->PCStats->QuickWeaponHeaders[action-ACT_WEAPON1]]); if (usedslot == slot) { btn->EnableBorder(0, true); if (core->GetGameControl()->target_mode&TARGET_MODE_ATTACK) { @@ -7244,6 +7245,7 @@ CREItem *item = actor->inventory.GetSlotItem(slot); if (item) { SetItemIcon(wi, ci, item->ItemResRef,0,(item->Flags&IE_INV_ITEM_IDENTIFIED)?2:1, i+1, 0); + SetItemText(wi, ci, item->Usages[actor->PCStats->QuickItemHeaders[tmp]]); } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-03-31 09:26:24
|
Revision: 4563 http://gemrb.svn.sourceforge.net/gemrb/?rev=4563&view=rev Author: avenger_teambg Date: 2007-03-31 02:26:23 -0700 (Sat, 31 Mar 2007) Log Message: ----------- implemented using items on others Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Actions.cpp gemrb/trunk/gemrb/plugins/Core/Actor.h gemrb/trunk/gemrb/plugins/Core/GameControl.cpp gemrb/trunk/gemrb/plugins/Core/GameControl.h gemrb/trunk/gemrb/plugins/Core/GameScript.cpp gemrb/trunk/gemrb/plugins/Core/GameScript.h gemrb/trunk/gemrb/plugins/Core/Item.h gemrb/trunk/gemrb/plugins/Core/Projectile.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-03-31 09:20:39 UTC (rev 4562) +++ gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-03-31 09:26:23 UTC (rev 4563) @@ -2055,6 +2055,32 @@ parameters->pointParameter, parameters->int0Parameter, true); } +void GameScript::Spell(Scriptable* Sender, Action* parameters) +{ + ieResRef spellres; + + if (!ResolveSpellName( spellres, parameters) ) { + Sender->ReleaseCurrentAction(); + return; + } + + Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); + if (!tar) { + Sender->ReleaseCurrentAction(); + return; + } + if (Sender->Type == ST_ACTOR) { + Actor *actor = (Actor *) Sender; + actor->SetStance (IE_ANI_CAST); + } + Point s,d; + GetPositionFromScriptable( Sender, s, false ); + GetPositionFromScriptable( tar, d, false ); + printf( "Spell from [%d,%d] to [%d,%d]\n", s.x, s.y, d.x, d.y ); + //this might be bad + Sender->ReleaseCurrentAction(); +} + //it is unsure how the ForceSpell actions differ void GameScript::ForceSpell(Scriptable* Sender, Action* parameters) { @@ -5070,7 +5096,7 @@ } int Slot, header; Actor *scr = (Actor *) Sender; - if (parameters->string0Parameter) { + if (parameters->string0Parameter[0]) { Slot = scr->inventory.FindItem(parameters->string0Parameter, 0); //this is actually not in the original game code header = parameters->int0Parameter; Modified: gemrb/trunk/gemrb/plugins/Core/Actor.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-03-31 09:20:39 UTC (rev 4562) +++ gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-03-31 09:26:23 UTC (rev 4563) @@ -95,6 +95,8 @@ #define GA_SELECT 16 //dead actor may not be selected #define GA_NO_DEAD 32 +//any point could be selected (area effect) +#define GA_POINT 64 #define GUIBT_COUNT 12 Modified: gemrb/trunk/gemrb/plugins/Core/GameControl.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameControl.cpp 2007-03-31 09:20:39 UTC (rev 4562) +++ gemrb/trunk/gemrb/plugins/Core/GameControl.cpp 2007-03-31 09:26:23 UTC (rev 4563) @@ -90,6 +90,9 @@ //maybe we don't even need it //action = GA_DEFAULT | GA_SELECT | GA_NO_DEAD; Changed = true; + spellOrItem = 0; + spellCount = 0; + user = NULL; lastActorID = 0; MouseIsDown = false; DrawSelectionRect = false; @@ -947,6 +950,69 @@ targetID = tmp; } +void GameControl::TryToCast(Actor *source, Point &tgt) +{ + char Tmp[40]; + + if (!spellCount) spellOrItem = 0; + if (!spellOrItem) return; //not casting or using an own item + spellCount--; + if (!spellOrItem) return; //not casting or using an own item + if (spellOrItem>0) { + CREMemorizedSpell *si; + //spell casting at target + si = source->spellbook.GetMemorizedSpell(spellOrItem, spellSlot, spellIndex); + sprintf(Tmp, "SpellPoint([%d.%d], %s)", tgt.x, tgt.y, si->SpellResRef ); + } else { + //using item on target + sprintf(Tmp, "UseItemPoint(\"\",[%d.%d],%d,%d)", tgt.x,tgt.y,spellIndex, spellSlot ); + } + source->AddAction( GenerateAction( Tmp) ); + if (!spellCount) { + spellOrItem = 0; + target_mode = TARGET_MODE_NONE; + } +} + +void GameControl::TryToCast(Actor *source, Actor *tgt) +{ + char Tmp[40]; + ieWord tmp; + + if (!spellCount) spellOrItem = 0; + if (!spellOrItem) return; //not casting or using an own item + spellCount--; + if (spellOrItem>0) { + sprintf(Tmp, "NIDSpecial6()"); + } else { + //using item on target + sprintf(Tmp, "NIDSpecial5()"); + } + tmp = targetID; + targetID=tgt->globalID; //this is a hack, not deadly, but a hack + Action* action = GenerateAction( Tmp); + source->AddAction( action ); + if (spellOrItem>0) + { + CREMemorizedSpell *si; + //spell casting at target + si = source->spellbook.GetMemorizedSpell(spellOrItem, spellSlot, spellIndex); + sprintf(action->string0Parameter,"%.8s",si->SpellResRef); + } + else + { + action->int0Parameter=spellSlot; + action->int1Parameter=spellIndex; + } + //we restore the old target ID, because this variable is primarily + //to keep track of the target of a dialog, and attacking isn't talking + targetID = tmp; + if (!spellCount) { + spellOrItem = 0; + target_mode = TARGET_MODE_NONE; + } +} + void GameControl::TryToTalk(Actor *source, Actor *tgt) { char Tmp[40]; @@ -966,6 +1032,11 @@ { char Tmp[256]; + if (spellOrItem) { + //we'll get the container back from the coordinates + TryToCast(actor, container->Pos); + return; + } actor->ClearPath(); actor->ClearActions(); strncpy(Tmp,"UseContainer()",sizeof(Tmp) ); @@ -977,6 +1048,12 @@ { char Tmp[256]; + if (spellOrItem) { + //we'll get the door back from the coordinates + TryToCast(actor, door->Pos); + return; + } + if (door->IsOpen()) { actor->ClearPath(); actor->ClearActions(); @@ -992,6 +1069,12 @@ bool GameControl::HandleActiveRegion(InfoPoint *trap, Actor * actor, Point &p) { + if (spellOrItem) { + //we'll get the active region from the coordinates (if needed) + TryToCast(actor, p); + //don't bother with this region further + return true; + } switch(trap->Type) { case ST_TRAVEL: trap->Flags|=TRAP_RESET; @@ -1122,6 +1205,12 @@ //just a single actor, no formation if (game->selected.size()==1) { + //the player is using an item or spell on the ground + if (spellOrItem) { + TryToCast(core->GetFirstSelectedPC(), p); + return; + } + actor=game->selected[0]; actor->ClearPath(); actor->ClearActions(); @@ -1160,33 +1249,38 @@ type = actor->GetStat(IE_EA); if ( type >= EA_EVILCUTOFF ) { - type = 2; //hostile + type = ACT_ATTACK; //hostile } else if ( type > EA_CHARMED ) { - type = 1; //neutral + type = ACT_TALK; //neutral } else { - type = 0; //party + type = ACT_NONE; //party } if (target_mode&TARGET_MODE_ATTACK) { - type = 2; + type = ACT_ATTACK; } else if (target_mode&TARGET_MODE_TALK) { - type = 1; + type = ACT_TALK; } else if (target_mode&TARGET_MODE_CAST) { - type = 3; + type = ACT_CAST; } else if (target_mode&TARGET_MODE_DEFEND) { - type = 4; + type = ACT_DEFEND; } - target_mode = TARGET_MODE_NONE; + //we shouldn't zero this for two reasons in case of spell or item + //1. there could be multiple targets + //2. the target mode is important + if (!spellOrItem) { + target_mode = TARGET_MODE_NONE; + } switch (type) { - case 0: + case ACT_NONE: //none //clicked on a new party member // FIXME: call GameControl::SelectActor() instead //game->SelectActor( actor, true, SELECT_REPLACE ); SelectActor( game->InParty(actor) ); break; - case 1: + case ACT_TALK: //talk (first selected talks) if (game->selected.size()) { //if we are in PST modify this to NO! @@ -1199,15 +1293,20 @@ TryToTalk(source, actor); } break; - case 2: + case ACT_ATTACK: //all of them attacks the red circled actor for(i=0;i<game->selected.size();i++) { TryToAttack(game->selected[i], actor); } break; - case 3: //cast on target + case ACT_CAST: //cast on target or use item on target + if (game->selected.size()==1) { + Actor *source; + source = core->GetFirstSelectedPC(); + TryToCast(source, actor); + } break; - case 4: + case ACT_DEFEND: for(i=0;i<game->selected.size();i++) { TryToDefend(game->selected[i], actor); } @@ -2033,3 +2132,25 @@ { return GetActorByGlobalID(speakerID); } + +void GameControl::SetupItemUse(int slot, int header, Actor *u, int targettype, int cnt) +{ + spellOrItem = -1; + spellUser = u; + spellSlot = slot; + spellIndex = header; + //item use also uses the casting icon, this might be changed + target_mode = targettype|TARGET_MODE_CAST; + spellCount = cnt; +} + +void GameControl::SetupCasting(int type, int level, int idx, Actor *u, int targettype, int cnt) +{ + spellOrItem = type; + spellUser = u; + spellSlot = level; + spellIndex = idx; + target_mode = targettype|TARGET_MODE_CAST; + spellCount = cnt; +} + Modified: gemrb/trunk/gemrb/plugins/Core/GameControl.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameControl.h 2007-03-31 09:20:39 UTC (rev 4562) +++ gemrb/trunk/gemrb/plugins/Core/GameControl.h 2007-03-31 09:26:23 UTC (rev 4563) @@ -154,14 +154,23 @@ void HandleWindowHide(const char *WindowName, const char *WindowPosition); void HandleWindowReveal(const char *WindowName, const char *WindowPosition); void ReadFormations(); + +private: unsigned char LeftCount, BottomCount, RightCount, TopCount; DialogState* ds; Dialog* dlg; + Actor *user; //the user of item or spell public: ieWord speakerID; ieWord targetID; - //no idea if this is viable - Scriptable *targetOB; + //no idea if this is viable + Scriptable *targetOB; + //using spell or item + int spellOrItem; // -1 = item, otherwise the spell type + //the user of spell or item + Actor *spellUser; + int spellSlot, spellIndex; //or inventorySlot/itemHeader + int spellCount; //multiple targeting public: Actor *GetTarget(); Actor *GetSpeaker(); @@ -171,6 +180,8 @@ int HideGUI(); int UnhideGUI(); void TryToAttack(Actor *source, Actor *target); + void TryToCast(Actor *source, Point &p); + void TryToCast(Actor *source, Actor *target); void TryToDefend(Actor *source, Actor *target); void TryToTalk(Actor *source, Actor *target); void HandleContainer(Container *container, Actor *actor); @@ -194,6 +205,10 @@ Sprite2D* GetPreview(); /** Returns PC portrait for a currently running game */ Sprite2D* GetPortraitPreview(int pcslot); + /** Sets up targeting with spells or items */ + void SetupItemUse(int slot, int header, Actor *actor, int targettype, int cnt); + /** Page is the spell type + spell level info */ + void SetupCasting(int type, int level, int slot, Actor *actor, int targettype, int cnt); }; #endif Modified: gemrb/trunk/gemrb/plugins/Core/GameScript.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameScript.cpp 2007-03-31 09:20:39 UTC (rev 4562) +++ gemrb/trunk/gemrb/plugins/Core/GameScript.cpp 2007-03-31 09:26:23 UTC (rev 4563) @@ -647,6 +647,8 @@ {"nidspecial2", GameScript::NIDSpecial2,AF_BLOCKING},//we use this for worldmap, another hack {"nidspecial3", GameScript::Attack,AF_BLOCKING|AF_DIRECT},//this hack is for attacking preset target {"nidspecial4", GameScript::ProtectObject,AF_BLOCKING|AF_DIRECT}, + {"nidspecial5", GameScript::UseItem, AF_BLOCKING|AF_DIRECT}, + {"nidspecial6", GameScript::Spell, AF_BLOCKING|AF_DIRECT}, {"noaction", GameScript::NoAction, 0}, {"opendoor", GameScript::OpenDoor,AF_BLOCKING}, {"panic", GameScript::Panic, 0}, Modified: gemrb/trunk/gemrb/plugins/Core/GameScript.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameScript.h 2007-03-31 09:20:39 UTC (rev 4562) +++ gemrb/trunk/gemrb/plugins/Core/GameScript.h 2007-03-31 09:26:23 UTC (rev 4563) @@ -1316,6 +1316,7 @@ static void SpawnPtActivate(Scriptable* Sender, Action* parameters); static void SpawnPtDeactivate(Scriptable* Sender, Action* parameters); static void SpawnPtSpawn(Scriptable* Sender, Action* parameters); + static void Spell(Scriptable* Sender, Action* parameters); static void SpellHitEffectSprite(Scriptable* Sender, Action* parameters); static void StartCutScene(Scriptable* Sender, Action* parameters); static void StartCutSceneMode(Scriptable* Sender, Action* parameters); Modified: gemrb/trunk/gemrb/plugins/Core/Item.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Item.h 2007-03-31 09:20:39 UTC (rev 4562) +++ gemrb/trunk/gemrb/plugins/Core/Item.h 2007-03-31 09:26:23 UTC (rev 4563) @@ -82,6 +82,16 @@ #define ITEM_AT_MAGIC 3 #define ITEM_AT_BOW 4 +//target types +#define TARGET_INVALID 0 //all the rest (default) +#define TARGET_CREA 1 //single living creature +#define TARGET_INV 2 //inventory item (not used?) +#define TARGET_DEAD 3 //creature, item or point +#define TARGET_AREA 4 //point target +#define TARGET_SELF 5 //self +#define TARGET_UNKNOWN 6 //unknown (use default) +#define TARGET_NONE 7 //self + //projectile qualifiers #define PROJ_ARROW 1 #define PROJ_BOLT 2 Modified: gemrb/trunk/gemrb/plugins/Core/Projectile.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Projectile.cpp 2007-03-31 09:20:39 UTC (rev 4562) +++ gemrb/trunk/gemrb/plugins/Core/Projectile.cpp 2007-03-31 09:26:23 UTC (rev 4563) @@ -85,8 +85,10 @@ //Pass means passing/rebounding/extinguishing on walls void Projectile::MoveLine(int steps, int Pass, ieDword orient) { - //remove previous path - ClearPath(); + //call this with destination + if (path) { + return; + } if (!steps) { Pos = Destination; return; @@ -153,7 +155,7 @@ if (Target) { Actor *target = area->GetActorByGlobalID(Target); if (!target) { - return; + return; } //deliver payload to target effects->AddAllEffects(target); @@ -168,7 +170,7 @@ void Projectile::DoStep(unsigned int walk_speed) { - if (!path || !walk_speed) { + if (!path) { ChangePhase(); return; } @@ -178,11 +180,10 @@ timeStartStep = time; } if (( time - timeStartStep ) >= walk_speed) { - //printf("[New Step] : Orientation = %d\n", step->orient); step = step->Next; timeStartStep = time; } - + SetOrientation (step->orient, false); Pos.x = ( step->x * 16 ) + 8; @@ -193,6 +194,9 @@ ChangePhase(); return; } + if (!walk_speed) { + return; + } if (step->Next->x > step->x) Pos.x += ( unsigned short ) ( ( ( ( ( step->Next->x * 16 ) + 8 ) - Pos.x ) * ( time - timeStartStep ) ) / walk_speed ); @@ -209,8 +213,8 @@ void Projectile::SetTarget(Point &p) { + ClearPath(); Destination = p; - ClearPath(); MoveLine( Speed, true, GetOrient(p, Pos) ); } Modified: gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp 2007-03-31 09:20:39 UTC (rev 4562) +++ gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp 2007-03-31 09:26:23 UTC (rev 4563) @@ -506,6 +506,22 @@ return false; } +bool Spellbook::DepleteSpell(int type, unsigned int page, unsigned int slot) +{ + if (NUM_SPELL_TYPES<=type) { + return false; + } + if (spells[type].size()<=page) { + return false; + } + CRESpellMemorization* sm = spells[page][type]; + if (sm->memorized_spells.size()<=slot) { + return false; + } + CREMemorizedSpell* cms = sm->memorized_spells[slot]; + return DepleteSpell(cms); +} + bool Spellbook::ChargeSpell(CREMemorizedSpell* spl) { spl->Flags = 1; Modified: gemrb/trunk/gemrb/plugins/Core/Spellbook.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spellbook.h 2007-03-31 09:20:39 UTC (rev 4562) +++ gemrb/trunk/gemrb/plugins/Core/Spellbook.h 2007-03-31 09:26:23 UTC (rev 4563) @@ -139,6 +139,8 @@ private: std::vector<CRESpellMemorization*> *spells; + /** Sets spell from memorized as 'already-cast' */ + bool DepleteSpell(CREMemorizedSpell* spl); public: Spellbook(); ~Spellbook(); @@ -183,7 +185,7 @@ bool ChargeSpell(CREMemorizedSpell* spl); /** Sets spell from memorized as 'already-cast' */ - bool DepleteSpell(CREMemorizedSpell* spl); + bool DepleteSpell(int type, unsigned int page, unsigned int slot); /** picks the highest spell of type and makes it 'already cast' */ bool DepleteSpell(int type); Modified: gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-03-31 09:20:39 UTC (rev 4562) +++ gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-03-31 09:26:23 UTC (rev 4563) @@ -7528,7 +7528,26 @@ printf("Target: %d\n",itemdata.Target); printf("Projectile: %d\n", itemdata.ProjectileAnimation); // - actor->UseItem(itemdata.slot, itemdata.headerindex, actor, silent); + switch (itemdata.Target) { + case TARGET_SELF: + actor->UseItem(itemdata.slot, itemdata.headerindex, actor, silent); + break; + case TARGET_NONE: + actor->UseItem(itemdata.slot, itemdata.headerindex, NULL, silent); + break; + case TARGET_AREA: + core->GetGameControl()->SetupItemUse(itemdata.slot, itemdata.headerindex, actor, GA_POINT, itemdata.TargetNumber); + break; + case TARGET_CREA: + core->GetGameControl()->SetupItemUse(itemdata.slot, itemdata.headerindex, actor, GA_NO_DEAD, itemdata.TargetNumber); + break; + case TARGET_DEAD: + core->GetGameControl()->SetupItemUse(itemdata.slot, itemdata.headerindex, actor, 0, itemdata.TargetNumber); + break; + default: + printMessage("GUIScript", "Unhandled target type!", LIGHT_RED ); + break; + } Py_INCREF( Py_None ); return Py_None; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-04-01 12:14:08
|
Revision: 4566 http://gemrb.svn.sourceforge.net/gemrb/?rev=4566&view=rev Author: avenger_teambg Date: 2007-04-01 05:14:08 -0700 (Sun, 01 Apr 2007) Log Message: ----------- small changes in effect opcodes Modified Paths: -------------- gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp Modified: gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-04-01 12:10:15 UTC (rev 4565) +++ gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-04-01 12:14:08 UTC (rev 4566) @@ -2386,6 +2386,8 @@ } //0x69 GoldModifier +//in BG2 this effect subtracts gold when type is MOD_ADDITIVE +//no one uses it, though. To keep the function, the default branch will do the subtraction int fx_gold_modifier (Actor* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_gold_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); @@ -2407,8 +2409,8 @@ gold = game->PartyGold*fx->Parameter1/100-game->PartyGold; break; default: - //ie crashes here, i guess - return FX_NOT_APPLIED; + gold = (ieDword) -fx->Parameter1; + break; } game->AddGold (gold); return FX_NOT_APPLIED; @@ -4579,8 +4581,9 @@ int fx_magical_rest (Actor* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_magical_rest (%2d)\n", fx->Opcode ); - target->Rest(0); //full rest - return FX_NOT_APPLIED; //this is an instant effect + //instant, full rest + target->Rest(0); + return FX_NOT_APPLIED; } // 0x13d ImprovedHaste Modified: gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-01 12:10:15 UTC (rev 4565) +++ gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-01 12:14:08 UTC (rev 4566) @@ -101,7 +101,9 @@ int fx_play_bam (Actor* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_play_bam (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); - target->add_animation(fx->Resource, -1, 0, false); + //play once set to true + //check tearring.itm (0xbb effect) + target->add_animation(fx->Resource, -1, 0, AA_BLEND|AA_PLAYONCE); return FX_NOT_APPLIED; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-04-04 19:31:22
|
Revision: 4568 http://gemrb.svn.sourceforge.net/gemrb/?rev=4568&view=rev Author: avenger_teambg Date: 2007-04-04 12:31:15 -0700 (Wed, 04 Apr 2007) Log Message: ----------- implemented play bam (0xbb) opcode of PST fully (tint, double anims, repeat flag, sticky flag) Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Palette.cpp gemrb/trunk/gemrb/plugins/Core/Palette.h gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.h gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp Modified: gemrb/trunk/gemrb/plugins/Core/Palette.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Palette.cpp 2007-04-01 12:15:11 UTC (rev 4567) +++ gemrb/trunk/gemrb/plugins/Core/Palette.cpp 2007-04-04 19:31:15 UTC (rev 4568) @@ -182,7 +182,7 @@ } void Palette::SetupRGBModification(const Palette* src, const RGBModifier* mods, - unsigned int type) + unsigned int type) { const RGBModifier* tmods = mods+(8*type); int i; @@ -231,7 +231,7 @@ } void Palette::SetupGlobalRGBModification(const Palette* src, - const RGBModifier& mod) + const RGBModifier& mod) { int i; for (i = 0; i < 4; ++i) @@ -248,3 +248,16 @@ } + +//only the shadow and transparent slot isn't tinted +void Palette::SetupCompleteRGBModification(const Palette* src, + const RGBModifier& mod) +{ + int i; + + for (i = 0; i < 2; ++i) + col[i] = src->col[i]; + + for (i = 0; i < 254; ++i) + applyMod(src->col[0x02+i],col[0x02+i],mod); +} Modified: gemrb/trunk/gemrb/plugins/Core/Palette.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Palette.h 2007-04-01 12:15:11 UTC (rev 4567) +++ gemrb/trunk/gemrb/plugins/Core/Palette.h 2007-04-04 19:31:15 UTC (rev 4568) @@ -98,9 +98,11 @@ void SetupPaperdollColours(ieDword* Colors, unsigned int type); void SetupRGBModification(const Palette* src, const RGBModifier* mods, - unsigned int type); + unsigned int type); void SetupGlobalRGBModification(const Palette* src, - const RGBModifier& mod); + const RGBModifier& mod); + void SetupCompleteRGBModification(const Palette* src, + const RGBModifier& mod); Palette* Copy(); Modified: gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp 2007-04-01 12:15:11 UTC (rev 4567) +++ gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp 2007-04-04 19:31:15 UTC (rev 4568) @@ -55,7 +55,8 @@ Duration = 0xffffffff; justCreated = true; PaletteName[0]=0; - SetPhase(P_ONSET); + twin = NULL; + Phase = P_NOTINITED; } void ScriptedAnimation::Override(ScriptedAnimation *templ) @@ -100,11 +101,23 @@ } /* Creating animation from BAM */ -void ScriptedAnimation::LoadAnimationFactory(AnimationFactory *af) +void ScriptedAnimation::LoadAnimationFactory(AnimationFactory *af, bool gettwin) { //getcycle returns NULL if there is no such cycle + //special case, PST double animations + bool dcyc; + if (af->GetCycleCount()==6) { + dcyc=true; + } else { + dcyc=false; + } for(unsigned int i=0;i<3;i++) { - anims[i] = af->GetCycle( (ieByte) i ); + int c = i; + if (dcyc) { + c<<=1; + if (gettwin) c++; + } + anims[i] = af->GetCycle( (ieByte) c ); palettes[i] = NULL; sounds[i][0] = 0; if (anims[i]) { @@ -124,6 +137,17 @@ anims[P_RELEASE]->Flags |= S_ANI_PLAYONCE; memcpy(ResName, af->ResRef, sizeof(ResName) ); + //we are getting a twin, no need of going further, + //if there is any more common initialisation, it should + //go above this point + if (gettwin) { + return; + } + if (dcyc) { + twin = new ScriptedAnimation(); + twin->LoadAnimationFactory(af, true); + } + SetPhase(P_ONSET); } /* Creating animation from VVC */ @@ -242,6 +266,9 @@ if (cover) { SetSpriteCover(NULL); } + if (twin) { + delete twin; + } } void ScriptedAnimation::SetPhase(int arg) @@ -250,12 +277,17 @@ Phase = arg; } SetSpriteCover(NULL); + if (twin) { + twin->SetPhase(Phase); + } } void ScriptedAnimation::SetSound(int arg, const ieResRef sound) { - if (arg>=P_ONSET && arg<=P_RELEASE) + if (arg>=P_ONSET && arg<=P_RELEASE) { memcpy(sounds[arg],sound,sizeof(sound)); + } + //no need to call the twin } void ScriptedAnimation::PlayOnce() @@ -266,6 +298,9 @@ anims[i]->Flags |= S_ANI_PLAYONCE; } } + if (twin) { + twin->PlayOnce(); + } } void ScriptedAnimation::SetFullPalette(const ieResRef PaletteResRef) @@ -283,6 +318,9 @@ palettes[i]=core->GetPalette(PaletteResRef); } memcpy(PaletteName, PaletteResRef, sizeof(PaletteName) ); + if (twin) { + twin->SetFullPalette(PaletteResRef); + } } void ScriptedAnimation::SetFullPalette(int idx) @@ -293,6 +331,7 @@ snprintf(PaletteResRef,sizeof(PaletteResRef),"%.7s%d",ResName, idx); strnlwrcpy(PaletteResRef,PaletteResRef,8); SetFullPalette(PaletteResRef); + //no need to call twin } #define PALSIZE 12 @@ -320,21 +359,41 @@ memcpy( &palettes[i]->col[start], NewPal, PALSIZE*sizeof( Color ) ); } } + if (twin) { + twin->SetPalette(gradient, start); + } } +ieDword ScriptedAnimation::GetSequenceDuration(ieDword multiplier) +{ + return anims[1]->GetFrameCount()*multiplier/FrameRate; +} + void ScriptedAnimation::SetDefaultDuration(ieDword duration) { if (Duration==0xffffffff) { Duration = duration; } + if (twin) { + twin->Duration=Duration; + } } //it is not sure if we need tint at all bool ScriptedAnimation::Draw(Region &screen, Point &Pos, Color &p_tint, Map *area, int p_dither) { + // not sure + if (twin) { + twin->Draw(screen, Pos, p_tint, area, p_dither); + } + Video *video = core->GetVideoDriver(); if (justCreated) { + if (Phase == P_NOTINITED) { + printMessage("ScriptedAnimation", "Not fully initialised VVC!", LIGHT_RED); + return true; + } justCreated = false; if (Duration!=0xffffffff) { Duration += core->GetGame()->Ticks; @@ -430,4 +489,36 @@ PrepareAnimation(anims[i], palettes[i], IE_VVC_BLENDED); } } + if (twin) { + twin->SetBlend(); + } } + +void ScriptedAnimation::AlterPalette(const RGBModifier& mod) +{ + for(unsigned int i=0;i<3;i++) { + if (anims[i]) { + if (!palettes[i]) { + Sprite2D* spr = anims[i]->GetFrame(0); + if (!spr) return; + palettes[i] = core->GetVideoDriver()->GetPalette(spr)->Copy(); + } + palettes[i]->SetupCompleteRGBModification(palettes[i],mod); + } + } + if (twin) { + twin->AlterPalette(mod); + } +} + +ScriptedAnimation *ScriptedAnimation::DetachTwin() +{ + if (!twin) { + return NULL; + } + ScriptedAnimation * ret = twin; + ret->YPos+=ret->ZPos+1; + ret->ZPos=-1; + twin=NULL; + return ret; +} Modified: gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.h 2007-04-01 12:15:11 UTC (rev 4567) +++ gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.h 2007-04-04 19:31:15 UTC (rev 4568) @@ -39,6 +39,7 @@ #define IE_VVC_UNUSED 0xe0000000U //phases +#define P_NOTINITED -1 #define P_ONSET 0 #define P_HOLD 1 #define P_RELEASE 2 @@ -49,7 +50,7 @@ ~ScriptedAnimation(void); ScriptedAnimation(DataStream* stream, bool autoFree = true); void Init(); - void LoadAnimationFactory(AnimationFactory *af); + void LoadAnimationFactory(AnimationFactory *af, bool gettwin = false); void Override(ScriptedAnimation *templ); //there are 3 phases: start, hold, release //it will usually cycle in the 2. phase @@ -69,6 +70,7 @@ ieResRef ResName; int Phase; SpriteCover* cover; + ScriptedAnimation *twin; public: //draws the next frame of the videocell bool Draw(Region &screen, Point &Pos, Color &tint, Map *area, int dither); @@ -88,10 +90,15 @@ void SetSpriteCover(SpriteCover* c) { delete cover; cover = c; } /* get stored SpriteCover */ SpriteCover* GetSpriteCover() const { return cover; } + ieDword GetSequenceDuration(ieDword multiplier); /* sets default duration if it wasn't set yet */ void SetDefaultDuration(unsigned int duration); /* transforms vvc to blended */ void SetBlend(); + /* alters palette with rgb factor */ + void AlterPalette(const RGBModifier &rgb); + /* returns possible twin after altering it to become underlay */ + ScriptedAnimation *DetachTwin(); private: void PrepareAnimation(Animation *anim, Palette *&palette, ieDword Transparency); }; Modified: gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-01 12:15:11 UTC (rev 4567) +++ gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-04 19:31:15 UTC (rev 4568) @@ -31,7 +31,8 @@ int fx_set_status (Actor* Owner, Actor* target, Effect* fx);//ba -int fx_play_bam (Actor* Owner, Actor* target, Effect* fx);//bb,bc,bd,be,bf +int fx_play_bam_bb (Actor* Owner, Actor* target, Effect* fx);//bb +int fx_play_bam (Actor* Owner, Actor* target, Effect* fx);//bc,bd,be,bf int fx_transfer_hp (Actor* Owner, Actor* target, Effect* fx);//c0 //int fx_shake_screen (Actor* Owner, Actor* target, Effect* fx);//c1 already implemented int fx_flash_screen (Actor* Owner, Actor* target, Effect* fx);//c2 @@ -62,8 +63,8 @@ { "JumbleCurse", fx_jumble_curse, 0}, //d3 { "MoveView", fx_move_view, 0},//cd { "Overlay", fx_overlay, 0}, //c9 - { "PlayBAM1", fx_play_bam, 0}, //bb,bc,bd,be,bf - { "PlayBAM2", fx_play_bam, 0}, + { "PlayBAM1", fx_play_bam_bb, 0}, //bb + { "PlayBAM2", fx_play_bam, 0},//bc,bd,be,bf { "PlayBAM3", fx_play_bam, 0}, { "PlayBAM4", fx_play_bam, 0}, { "PlayBAM5", fx_play_bam, 0}, @@ -97,13 +98,109 @@ return FX_NOT_APPLIED; } -//bb,bc,bd,be,bf fx_play_bam +//bb fx_play_bam_bb (play blended animation) +int fx_play_bam_bb (Actor* /*Owner*/, Actor* target, Effect* fx) +{ + bool playonce; + + if (0) printf( "fx_play_bam_bb (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); + //play once set to true + //check tearring.itm (0xbb effect) + ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource); + if (!sca) + return FX_NOT_APPLIED; + + sca->SetBlend(); + //the transparency is based on the original palette + if (fx->Parameter1) { + RGBModifier rgb; + + rgb.speed=-1; + rgb.phase=0; + rgb.rgb.r=fx->Parameter1; + rgb.rgb.g=fx->Parameter1 >> 8; + rgb.rgb.b=fx->Parameter1 >> 16; + rgb.rgb.a=0; + rgb.type=RGBModifier::TINT; + sca->AlterPalette(rgb); + } + if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { + playonce=true; + } else { + playonce=false; + } + if (fx->Parameter2&1) { + //four cycles, duration is in millisecond + sca->SetDefaultDuration(sca->GetSequenceDuration(4000)); + } else { + if (playonce) { + sca->PlayOnce(); + } else { + sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks); + } + } + if (fx->Parameter2&2) { + sca->XPos+=fx->PosX; + sca->YPos+=fx->PosY; + //probably we should use Owner? + target->GetCurrentArea()->AddVVCell(sca); + } else { + ScriptedAnimation *twin = sca->DetachTwin(); + if (twin) { + target->AddVVCell(twin); + } + target->AddVVCell(sca); + } + return FX_NOT_APPLIED; +} + +//bc,bd,be,bf fx_play_bam +//these are not yet fully implemented int fx_play_bam (Actor* /*Owner*/, Actor* target, Effect* fx) { + bool playonce; + if (0) printf( "fx_play_bam (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); //play once set to true //check tearring.itm (0xbb effect) - target->add_animation(fx->Resource, -1, 0, AA_BLEND|AA_PLAYONCE); + ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource); + if (!sca) + return FX_NOT_APPLIED; + if (fx->Parameter1) { + RGBModifier rgb; + + rgb.speed=-1; + rgb.phase=0; + rgb.rgb.r=fx->Parameter1; + rgb.rgb.g=fx->Parameter1 >> 8; + rgb.rgb.b=fx->Parameter1 >> 16; + rgb.rgb.a=fx->Parameter1 >> 24; + rgb.type=RGBModifier::TINT; + sca->AlterPalette(rgb); + } + if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { + playonce=true; + } else { + playonce=false; + } + if (fx->Parameter2&1) { + //four cycles, duration is in millisecond + sca->SetDefaultDuration(sca->GetSequenceDuration(4000)); + } else { + if (playonce) { + sca->PlayOnce(); + } else { + sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks); + } + } + sca->SetBlend(); + if (fx->Parameter2&2) { + sca->XPos+=fx->PosX; + sca->YPos+=fx->PosY; + target->GetCurrentArea()->AddVVCell(sca); + } else { + target->AddVVCell(sca); + } return FX_NOT_APPLIED; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-04-07 00:39:20
|
Revision: 4572 http://gemrb.svn.sourceforge.net/gemrb/?rev=4572&view=rev Author: avenger_teambg Date: 2007-04-06 17:39:21 -0700 (Fri, 06 Apr 2007) Log Message: ----------- refactored ScriptedAnimation (VVC) to have multiple orientations (face target) removed multiple palettes from VVC improved pst bam player for bams with orientations improved effect targeting added spell casting to actors Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Actions.cpp gemrb/trunk/gemrb/plugins/Core/Actor.cpp gemrb/trunk/gemrb/plugins/Core/Actor.h gemrb/trunk/gemrb/plugins/Core/ActorBlock.h gemrb/trunk/gemrb/plugins/Core/Effect.h gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp gemrb/trunk/gemrb/plugins/Core/EffectQueue.h gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp gemrb/trunk/gemrb/plugins/Core/GameControl.cpp gemrb/trunk/gemrb/plugins/Core/Interface.cpp gemrb/trunk/gemrb/plugins/Core/Interface.h gemrb/trunk/gemrb/plugins/Core/Makefile.am gemrb/trunk/gemrb/plugins/Core/Map.cpp gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.h gemrb/trunk/gemrb/plugins/Core/Spell.cpp gemrb/trunk/gemrb/plugins/Core/Spell.h gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp gemrb/trunk/gemrb/plugins/Core/Spellbook.h gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp gemrb/trunk/gemrb/plugins/IWDOpcodes/IWDOpc.cpp gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp gemrb/trunk/gemrb/plugins/SPLImporter/SPLImp.cpp Modified: gemrb/trunk/gemrb/plugins/Core/Actions.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-04-07 00:39:21 UTC (rev 4572) @@ -5487,7 +5487,7 @@ } Actor *actor = (Actor *)tar; RebusResRef[5]=(char) core->Roll(1,5,'0'); - ScriptedAnimation *vvc = core->GetScriptedAnimation(RebusResRef); + ScriptedAnimation *vvc = core->GetScriptedAnimation(RebusResRef, 0); if (vvc) { //setting the height vvc->ZPos=actor->size*20; Modified: gemrb/trunk/gemrb/plugins/Core/Actor.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-04-07 00:39:21 UTC (rev 4572) @@ -3015,19 +3015,6 @@ Projectile *pro = itm->GetProjectile(header); pro->SetCaster(globalID); GetCurrentArea()->AddProjectile(pro, Pos, target); - //in fact this should build a projectile and hurl it at the target - //this is just a temporary solution - /* - EffectQueue *fx = itm->GetEffectBlock(header); - if (!fx) - return false; - Actor *tar=GetCurrentArea()->GetActor(target, 10); - if (tar) { - fx->SetOwner(this); - fx->AddAllEffects(tar); - } - */ - // ChargeItem(slot, header, item, itm, silent); core->FreeItem(itm,item->ItemResRef, false); return true; @@ -3053,16 +3040,6 @@ pro->SetCaster(globalID); GetCurrentArea()->AddProjectile(pro, Pos, tar->globalID); } - //in fact this should build a projectile and hurl it at the target - //this is just a temporary solution - /* - EffectQueue *fx = itm->GetEffectBlock(header); - if (!fx) - return false; - fx->SetOwner(this); - fx->AddAllEffects(tar); - */ - // ChargeItem(slot, header, item, itm, silent); core->FreeItem(itm,item->ItemResRef, false); return true; @@ -3093,6 +3070,47 @@ } } +bool Actor::CastSpellPoint( ieResRef SpellResRef, Point &target ) +{ + if (! spellbook.HaveSpell( SpellResRef, HS_DEPLETE )) { + return false; + } + + Spell* spl = core->GetSpell( SpellResRef ); + //cfb + EffectQueue *fxqueue=spl->GetEffectBlock(-1); + fxqueue->SetOwner(this); + fxqueue->ApplyAllEffects(this); + //spell + Projectile *pro=spl->GetProjectile(GetXPLevel(true)); + pro->SetCaster(globalID); + GetCurrentArea()->AddProjectile(pro, Pos, target); + return true; +} + +bool Actor::CastSpell( ieResRef SpellResRef, Scriptable* target ) +{ + if (! spellbook.HaveSpell( SpellResRef, HS_DEPLETE )) { + return false; + } + + if (target->Type!=ST_ACTOR) { + return CastSpellPoint(SpellResRef, target->Pos); + } + + Actor *Target = (Actor *) target; + Spell* spl = core->GetSpell( SpellResRef ); + //cfb + EffectQueue *fxqueue=spl->GetEffectBlock(-1); + fxqueue->SetOwner(this); + fxqueue->ApplyAllEffects(this); + //spell + Projectile *pro=spl->GetProjectile(GetXPLevel(true)); + pro->SetCaster(globalID); + GetCurrentArea()->AddProjectile(pro, Pos, Target->globalID); + return true; +} + bool Actor::IsReverseToHit() { return REVERSE_TOHIT; Modified: gemrb/trunk/gemrb/plugins/Core/Actor.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-04-07 00:39:21 UTC (rev 4572) @@ -435,6 +435,9 @@ bool UseItem(int slot, ieDword header, Scriptable *target, bool silent); /* Deducts a charge from an item */ void ChargeItem(int slot, ieDword header, CREItem *item, Item *itm, bool silent); + /* actor casts spell */ + bool CastSpellPoint( ieResRef SpellResRef, Point &Target ); + bool CastSpell( ieResRef SpellResRef, Scriptable* Target ); /* If it returns true, then default AC=10 and the lesser the better */ bool IsReverseToHit(); void InitButtons(ieDword cls); Modified: gemrb/trunk/gemrb/plugins/Core/ActorBlock.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/ActorBlock.h 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/ActorBlock.h 2007-04-07 00:39:21 UTC (rev 4572) @@ -342,7 +342,7 @@ return Orientation; } - inline unsigned char GetStance() { + inline unsigned char GetStance() const { return StanceID; } Modified: gemrb/trunk/gemrb/plugins/Core/Effect.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Effect.h 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/Effect.h 2007-04-07 00:39:21 UTC (rev 4572) @@ -21,7 +21,7 @@ /** * @file Effect.h - * Declares Effect class implementing spell and spell-like effects + * Declares Effect class implementing spell and spell-like effects * and related defines */ @@ -43,6 +43,7 @@ #define FX_TARGET_PARTY 3 #define FX_TARGET_GLOBAL_INCL_PARTY 4 #define FX_TARGET_GLOBAL_EXCL_PARTY 5 +#define FX_TARGET_ORIGINAL 9 // Effect duration/timing types #define FX_DURATION_INSTANT_LIMITED 0 @@ -109,6 +110,6 @@ }; // FIXME: what about area spells? They can have map & coordinates as target -void AddEffect(Effect* fx, Actor* self, Actor* pretarget); +//void AddEffect(Effect* fx, Actor* self, Actor* pretarget); #endif // ! EFFECT_H Modified: gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp 2007-04-07 00:39:21 UTC (rev 4572) @@ -343,7 +343,81 @@ } } +bool EffectQueue::AddEffect(Effect* fx, Actor* self, Actor* pretarget) +{ + int i; + Game *game; + Map *map; + bool flg; + switch (fx->Target) { + case FX_TARGET_ORIGINAL: + flg = self->fxqueue.ApplyEffect( self, fx, true ); + if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { + self->fxqueue.AddEffect( fx ); + } + break; + case FX_TARGET_SELF: + flg = self->fxqueue.ApplyEffect( self, fx, true ); + if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { + self->fxqueue.AddEffect( fx ); + } + break; + + case FX_TARGET_PRESET: + flg = self->fxqueue.ApplyEffect( pretarget, fx, true ); + if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { + pretarget->fxqueue.AddEffect( fx ); + } + break; + + case FX_TARGET_PARTY: + game=core->GetGame(); + for (i = game->GetPartySize(true); i >= 0; i--) { + Actor* actor = game->GetPC( i, true ); + self->fxqueue.ApplyEffect( actor, fx, true ); + if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { + actor->fxqueue.AddEffect( fx ); + } + } + flg = false; + break; + + case FX_TARGET_GLOBAL_INCL_PARTY: + map=self->GetCurrentArea(); + for (i = map->GetActorCount(true); i >= 0; i--) { + Actor* actor = map->GetActor( i, true ); + self->fxqueue.ApplyEffect( actor, fx, true ); + if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { + actor->fxqueue.AddEffect( fx ); + } + } + flg = false; + break; + + case FX_TARGET_GLOBAL_EXCL_PARTY: + map=self->GetCurrentArea(); + for (i = map->GetActorCount(false); i >= 0; i--) { + Actor* actor = map->GetActor( i, false ); + self->fxqueue.ApplyEffect( actor, fx, true ); + //GetActorCount can now return all nonparty critters + //if (actor->InParty) continue; + if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { + actor->fxqueue.AddEffect( fx ); + } + } + flg = false; + break; + + case FX_TARGET_UNKNOWN: + default: + printf( "Unknown FX target type: %d\n", fx->Target); + flg = false; + break; + } + return flg; +} + //this is where effects from spells first get in touch with the target //the effects are currently NOT in the target's fxqueue, those that stick //will get copied (hence the fxqueue.AddEffect call) @@ -359,11 +433,8 @@ (*f)->PosX = target->Pos.x; (*f)->PosY = target->Pos.y; //if applyeffect returns true, we stop adding the future effects - bool flg = target->fxqueue.ApplyEffect( target, *f, true ); - if ((*f)->TimingMode!=FX_DURATION_JUST_EXPIRED) { - target->fxqueue.AddEffect(*f); - } - if (flg) { + //this is to simulate iwd2's on the fly spell resistance + if(AddEffect(*f, Owner, target)) { break; } } Modified: gemrb/trunk/gemrb/plugins/Core/EffectQueue.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/EffectQueue.h 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/EffectQueue.h 2007-04-07 00:39:21 UTC (rev 4572) @@ -156,6 +156,7 @@ * Returns true is successful. fx is just a reference, AddEffect() * will malloc its own copy */ bool AddEffect(Effect* fx); + bool AddEffect(Effect* fx, Actor* self, Actor* pretarget); /** Removes first Effect matching fx from the queue. * Effects are matched based on their contents */ bool RemoveEffect(Effect* fx); Modified: gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp 2007-04-07 00:39:21 UTC (rev 4572) @@ -694,7 +694,7 @@ //TODO: add engine specific VVC replacement methods //stick to object flag, sounds, iterations etc. if (effect[0]) { - ScriptedAnimation* vvc = core->GetScriptedAnimation(effect); + ScriptedAnimation* vvc = core->GetScriptedAnimation(effect, false); if (!vvc) { printMessage("GameScript","Failed to create effect.",LIGHT_RED); return; Modified: gemrb/trunk/gemrb/plugins/Core/GameControl.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameControl.cpp 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/GameControl.cpp 2007-04-07 00:39:21 UTC (rev 4572) @@ -589,7 +589,7 @@ case 'c': if (game->selected.size() > 0 && lastActor) { Actor *src = game->selected[0]; - bool res = src->spellbook.CastSpell( "SPWI207", src, lastActor ); + bool res = src->CastSpell( "SPWI207", lastActor ); printf( "Cast Spell: %d\n", res ); } break; Modified: gemrb/trunk/gemrb/plugins/Core/Interface.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Interface.cpp 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/Interface.cpp 2007-04-07 00:39:21 UTC (rev 4572) @@ -2480,7 +2480,7 @@ map->AddActor(ab); ab->SetPosition(position, true, 0); if (vvcres[0]) { - ScriptedAnimation* vvc = GetScriptedAnimation(vvcres); + ScriptedAnimation* vvc = GetScriptedAnimation(vvcres, false); vvc->XPos=position.x; vvc->YPos=position.y; map->AddVVCell( vvc ); @@ -4788,7 +4788,7 @@ //if the default setup doesn't fit for an animation //create a vvc for it! -ScriptedAnimation* Interface::GetScriptedAnimation( const char *effect) +ScriptedAnimation* Interface::GetScriptedAnimation( const char *effect, bool doublehint) { ScriptedAnimation *ret = NULL; @@ -4797,10 +4797,10 @@ ret = new ScriptedAnimation(ds, true); } else { AnimationFactory *af = (AnimationFactory *) - key->GetFactoryResource( effect, IE_BAM_CLASS_ID, IE_NORMAL ); + key->GetFactoryResource( effect, IE_BAM_CLASS_ID, IE_NORMAL ); if (af) { ret = new ScriptedAnimation(); - ret->LoadAnimationFactory( af); + ret->LoadAnimationFactory( af, doublehint?2:0); } } if (ret) { Modified: gemrb/trunk/gemrb/plugins/Core/Interface.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Interface.h 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/Interface.h 2007-04-07 00:39:21 UTC (rev 4572) @@ -557,7 +557,7 @@ /** returns true if resource exists */ bool Exists(const char *ResRef, SClass_ID type); /** creates a vvc/bam animation object at point */ - ScriptedAnimation* GetScriptedAnimation( const char *ResRef); + ScriptedAnimation* GetScriptedAnimation( const char *ResRef, bool doublehint); /** returns the first selected PC */ Actor *GetFirstSelectedPC(); /** returns a single sprite (not cached) from a BAM resource */ Modified: gemrb/trunk/gemrb/plugins/Core/Makefile.am =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Makefile.am 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/Makefile.am 2007-04-07 00:39:21 UTC (rev 4572) @@ -89,7 +89,6 @@ WorldMapControl.cpp \ MapControl.cpp \ AmbientMgr.cpp \ - Effect.cpp \ EffectQueue.cpp \ Cache.cpp \ ControlAnimation.cpp \ Modified: gemrb/trunk/gemrb/plugins/Core/Map.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Map.cpp 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/Map.cpp 2007-04-07 00:39:21 UTC (rev 4572) @@ -926,7 +926,7 @@ Color tint = LightMap->GetPixel( sca->XPos / 16, sca->YPos / 12); tint.a = 255; - bool endReached = sca->Draw(screen, Pos, tint, this, 0); + bool endReached = sca->Draw(screen, Pos, tint, this, 0, -1); if (endReached) { delete( sca ); scaidx=vvcCells.erase(scaidx); Modified: gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp 2007-04-07 00:39:21 UTC (rev 4572) @@ -28,6 +28,33 @@ #include "Video.h" #include "Game.h" +#define ILLEGAL 0 // +#define ONE 1 //hold +#define TWO 2 //onset + hold +#define THREE 3 //onset + hold + release +#define DOUBLE 4 //has twin (pst) +#define FIVE 8 //five faces (orientation) +#define NINE 16 //nine faces (orientation) + +#define MAX_CYCLE_TYPE 16 +// 0 1 2 3 4 5 6 7 +static ieByte ctypes[MAX_CYCLE_TYPE]= +{ ILLEGAL, ONE, TWO, THREE, TWO|DOUBLE, ONE|FIVE, THREE|DOUBLE, ILLEGAL, +// 8 9 10 11 12 13 14 15 + ILLEGAL,ONE|NINE, TWO|FIVE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,THREE|FIVE, +}; + +static ieByte SixteenToNine[3*MAX_ORIENT]={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, + 9,10,11,12,13,14,15,16,17,16,15,14,13,12,11,10, + 18,19,20,21,22,23,24,25,26,25,24,23,22,21,20,19 +}; +static ieByte SixteenToFive[3*MAX_ORIENT]={ + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 3, 3, 2, 2, 1, 1, + 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 8, 8, 7, 7, 6, 6, + 10,10,11,11,12,12,13,13,14,14,13,13,12,12,11,11 +}; + ScriptedAnimation::ScriptedAnimation() { Init(); @@ -36,12 +63,8 @@ void ScriptedAnimation::Init() { cover = NULL; - anims[0] = NULL; - anims[1] = NULL; - anims[2] = NULL; - palettes[0] = NULL; - palettes[1] = NULL; - palettes[2] = NULL; + memset(anims,0,sizeof(anims)); + palette = NULL; sounds[0][0] = 0; sounds[1][0] = 0; sounds[2][0] = 0; @@ -51,6 +74,7 @@ XPos = YPos = ZPos = 0; FrameRate = 15; FaceTarget = 0; + Orientation = 0; dither = 0; Duration = 0xffffffff; justCreated = true; @@ -80,7 +104,7 @@ } //prepare the animation before doing anything -void ScriptedAnimation::PrepareAnimation(Animation *anim, Palette *&palette, ieDword Transparency) +void ScriptedAnimation::PrepareAnimation(Animation *anim, ieDword Transparency) { if (Transparency&IE_VVC_MIRRORX) { anim->MirrorAnimation(); @@ -88,64 +112,114 @@ if (Transparency&IE_VVC_MIRRORY) { anim->MirrorAnimationVert(); } - + //make this the last if possible, because of the return if (Transparency&IE_VVC_BLENDED) { - if (!palette) { - Sprite2D* spr = anim->GetFrame(0); - if (!spr) return; - palette = core->GetVideoDriver()->GetPalette(spr)->Copy(); + GetPaletteCopy(); + if (!palette) + return; + if (!palette->alpha) { + palette->CreateShadedAlphaChannel(); } - palette->CreateShadedAlphaChannel(); } } /* Creating animation from BAM */ -void ScriptedAnimation::LoadAnimationFactory(AnimationFactory *af, bool gettwin) +void ScriptedAnimation::LoadAnimationFactory(AnimationFactory *af, int gettwin) { //getcycle returns NULL if there is no such cycle //special case, PST double animations - bool dcyc; - if (af->GetCycleCount()==6) { - dcyc=true; + + memcpy(ResName, af->ResRef, sizeof(ResName) ); + unsigned int cCount=af->GetCycleCount(); + if (cCount>=MAX_CYCLE_TYPE) { + cCount=1; + } + + int type = ctypes[cCount]; + switch(gettwin) { + case 2: + if (type==TWO) { + type=ONE|DOUBLE; + } + gettwin=0; + break; + case 1: + type=ONE|DOUBLE; + break; + } + + if (type==ILLEGAL) { + cCount=1; + type=ONE; + } + else if (type&DOUBLE) { + cCount/=2; + } + + //these fields mark that the anim cycles should 'follow' the target's orientation + if (type&FIVE) { + FaceTarget = 5; + cCount = MAX_ORIENT*(type&3); + } else if (type&NINE) { + FaceTarget = 9; + cCount = MAX_ORIENT*(type&3); } else { - dcyc=false; + FaceTarget = 0; } - for(unsigned int i=0;i<3;i++) { + + palette = NULL; + + for(unsigned int i=0;i<cCount;i++) { + bool mirror = false; int c = i; - if (dcyc) { + int p = i; + if (type&DOUBLE) { c<<=1; if (gettwin) c++; + } else if (type&FIVE) { + c=SixteenToFive[c]; + if ((i&15)>=5) mirror = true; + } else if (type&NINE) { + c=SixteenToNine[c]; + if ((i&15)>=9) mirror = true; + } else p*=MAX_ORIENT; + + anims[p] = af->GetCycle( (ieByte) c ); + if (anims[p]) { + anims[p]->pos=0; + if (mirror) { + anims[p]->MirrorAnimation(); + } + anims[p]->gameAnimation=true; } - anims[i] = af->GetCycle( (ieByte) c ); - palettes[i] = NULL; - sounds[i][0] = 0; - if (anims[i]) { - anims[i]->pos=0; - anims[i]->gameAnimation=true; + } + + for (unsigned int o = 0; o<MAX_ORIENT; o++) + { + unsigned int p_hold = P_HOLD*MAX_ORIENT+o; + unsigned int p_onset = P_ONSET*MAX_ORIENT+o; + unsigned int p_release = P_RELEASE*MAX_ORIENT+o; + //if there is no hold anim, move the onset anim there + if (!anims[p_hold]) { + anims[p_hold]=anims[p_onset]; + anims[p_onset]=NULL; } + //onset and release phases are to be played only once + if (anims[p_onset]) + anims[p_onset]->Flags |= S_ANI_PLAYONCE; + if (anims[p_release]) + anims[p_release]->Flags |= S_ANI_PLAYONCE; } - //if there is no hold anim, move the onset anim there - if (!anims[P_HOLD]) { - anims[P_HOLD]=anims[P_ONSET]; - anims[P_ONSET]=NULL; - } - //onset and release phases are to be played only once - if (anims[P_ONSET]) - anims[P_ONSET]->Flags |= S_ANI_PLAYONCE; - if (anims[P_RELEASE]) - anims[P_RELEASE]->Flags |= S_ANI_PLAYONCE; - - memcpy(ResName, af->ResRef, sizeof(ResName) ); //we are getting a twin, no need of going further, //if there is any more common initialisation, it should //go above this point if (gettwin) { return; } - if (dcyc) { + if (type&DOUBLE) { twin = new ScriptedAnimation(); - twin->LoadAnimationFactory(af, true); + twin->LoadAnimationFactory(af, 1); } SetPhase(P_ONSET); } @@ -208,7 +282,7 @@ //they certainly got onset and hold phases anims[P_ONSET] = af->GetCycle( ( unsigned char ) seq1 ); if (anims[P_ONSET]) { - PrepareAnimation(anims[P_ONSET], palettes[P_ONSET], Transparency); + PrepareAnimation(anims[P_ONSET], Transparency); //creature anims may start at random position, vvcs always start on 0 anims[P_ONSET]->pos=0; //vvcs are always paused @@ -218,7 +292,7 @@ anims[P_HOLD] = af->GetCycle( ( unsigned char ) seq2 ); if (anims[P_HOLD]) { - PrepareAnimation(anims[P_HOLD], palettes[P_HOLD], Transparency); + PrepareAnimation(anims[P_HOLD], Transparency); anims[P_HOLD]->pos=0; anims[P_HOLD]->gameAnimation=true; @@ -229,7 +303,7 @@ anims[P_RELEASE] = af->GetCycle( ( unsigned char ) seq3 ); if (anims[P_RELEASE]) { - PrepareAnimation(anims[P_RELEASE], palettes[P_RELEASE], Transparency); + PrepareAnimation(anims[P_RELEASE], Transparency); anims[P_RELEASE]->pos=0; anims[P_RELEASE]->gameAnimation=true; @@ -257,12 +331,13 @@ ScriptedAnimation::~ScriptedAnimation(void) { - for(unsigned int i=0;i<3;i++) { + for(unsigned int i=0;i<3*MAX_ORIENT;i++) { if (anims[i]) { delete( anims[i] ); - } - core->FreePalette(palettes[i], PaletteName); + } } + core->FreePalette(palette, PaletteName); + if (cover) { SetSpriteCover(NULL); } @@ -293,7 +368,7 @@ void ScriptedAnimation::PlayOnce() { SequenceFlags&=~IE_VVC_LOOP; - for (unsigned int i=0;i<3;i++) { + for (unsigned int i=0;i<3*MAX_ORIENT;i++) { if (anims[i]) { anims[i]->Flags |= S_ANI_PLAYONCE; } @@ -305,18 +380,8 @@ void ScriptedAnimation::SetFullPalette(const ieResRef PaletteResRef) { - unsigned int i; - - for(i=0;i<3;i++) { - if (!anims[i]) { - continue; - } - if (palettes[i]) { - core->FreePalette(palettes[i], PaletteName); - } - - palettes[i]=core->GetPalette(PaletteResRef); - } + core->FreePalette(palette, PaletteName); + palette=core->GetPalette(PaletteResRef); memcpy(PaletteName, PaletteResRef, sizeof(PaletteName) ); if (twin) { twin->SetFullPalette(PaletteResRef); @@ -339,26 +404,17 @@ void ScriptedAnimation::SetPalette(int gradient, int start) { - unsigned int i; - - for(i=0;i<3;i++) { - if (!palettes[i] && anims[i]) { - // We copy the palette of its first frame into our own palette - palettes[i]=core->GetVideoDriver()->GetPalette(anims[i]->GetFrame(0))->Copy(); - } - } - + //get a palette + GetPaletteCopy(); + if (!palette) + return; //default start if (start==-1) { start=4; } core->GetPalette( gradient&255, PALSIZE, NewPal ); - for(i=0;i<3;i++) { - if (palettes[i]) { - memcpy( &palettes[i]->col[start], NewPal, PALSIZE*sizeof( Color ) ); - } - } + memcpy( &palette->col[start], NewPal, PALSIZE*sizeof( Color ) ); if (twin) { twin->SetPalette(gradient, start); } @@ -366,7 +422,8 @@ ieDword ScriptedAnimation::GetSequenceDuration(ieDword multiplier) { - return anims[1]->GetFrameCount()*multiplier/FrameRate; + //P_HOLD * MAX_ORIENT == MAX_ORIENT + return anims[P_HOLD*MAX_ORIENT]->GetFrameCount()*multiplier/FrameRate; } void ScriptedAnimation::SetDefaultDuration(ieDword duration) @@ -379,16 +436,19 @@ } } -//it is not sure if we need tint at all -bool ScriptedAnimation::Draw(Region &screen, Point &Pos, Color &p_tint, Map *area, int p_dither) +void ScriptedAnimation::SetOrientation(int orientation) { - // not sure + if (orientation==-1) { + return; + } + Orientation=orientation; if (twin) { - twin->Draw(screen, Pos, p_tint, area, p_dither); + twin->Orientation=Orientation; } +} - Video *video = core->GetVideoDriver(); - +bool ScriptedAnimation::HandlePhase(Sprite2D *&frame) +{ if (justCreated) { if (Phase == P_NOTINITED) { printMessage("ScriptedAnimation", "Not fully initialised VVC!", LIGHT_RED); @@ -398,7 +458,8 @@ if (Duration!=0xffffffff) { Duration += core->GetGame()->Ticks; } - if (!anims[P_ONSET]) { + + if (!anims[P_ONSET*MAX_ORIENT+Orientation]) { Phase = P_HOLD; } retry: @@ -407,14 +468,14 @@ } } - if (!anims[Phase]) { + if (!anims[Phase*MAX_ORIENT+Orientation]) { if (Phase>=P_RELEASE) { return true; } Phase++; goto retry; } - Sprite2D* frame = anims[Phase]->NextFrame(); + frame = anims[Phase*MAX_ORIENT+Orientation]->NextFrame(); //explicit duration if (Phase==P_HOLD) { @@ -424,35 +485,53 @@ } } //automatically slip from onset to hold to release - if (!frame || anims[Phase]->endReached) { + if (!frame || anims[Phase*MAX_ORIENT+Orientation]->endReached) { if (Phase>=P_RELEASE) { return true; } Phase++; goto retry; } - ieDword flag = 0; + return false; +} + +//it is not sure if we need tint at all +bool ScriptedAnimation::Draw(Region &screen, Point &Pos, Color &p_tint, Map *area, int p_dither, int orientation) +{ + if (FaceTarget) { + SetOrientation(orientation); + } + + // not sure + if (twin) { + twin->Draw(screen, Pos, p_tint, area, p_dither, -1); + } + + Video *video = core->GetVideoDriver(); + + Sprite2D* frame; + + if (HandlePhase(frame)) { + return true; + } + + ieDword flag = BLIT_TRANSSHADOW; //transferring flags to SDLdriver, this will have to be consolidated later if (Transparency & IE_VVC_TRANSPARENT) { flag |= BLIT_HALFTRANS; } - if (Transparency & IE_VVC_BLENDED) { - flag |= BLIT_BLENDED; - } - - Color tint = {128,128,128,255}; + Color tint = {0,0,0,0}; //darken, greyscale, red tint are probably not needed if the global tint works //these are used in the original engine to implement weather/daylight effects //on the other hand - if (Transparency & IE_VVC_DARKEN) { - flag |= BLIT_TINTED; - } + if (Transparency & IE_VVC_GREYSCALE) { flag |= BLIT_GREY; } + if (Transparency & IE_VVC_RED_TINT) { flag |= BLIT_RED; } @@ -470,13 +549,14 @@ } else { if (!cover || (dither!=p_dither) || (!cover->Covers(cx, cy, frame->XPos, frame->YPos, frame->Width, frame->Height)) ) { dither = p_dither; - SetSpriteCover(area->BuildSpriteCover(cx, cy, -anims[Phase]->animArea.x, - -anims[Phase]->animArea.y, anims[Phase]->animArea.w, anims[Phase]->animArea.h, p_dither) ); + Animation *anim = anims[Phase*MAX_ORIENT+Orientation]; + SetSpriteCover(area->BuildSpriteCover(cx, cy, -anim->animArea.x, + -anim->animArea.y, anim->animArea.w, anim->animArea.h, p_dither) ); } assert(cover->Covers(cx, cy, frame->XPos, frame->YPos, frame->Width, frame->Height)); } - video->BlitGameSprite( frame, cx + screen.x, cy + screen.y, flag, tint, cover, palettes[Phase], &screen); + video->BlitGameSprite( frame, cx + screen.x, cy + screen.y, flag, tint, cover, palette, &screen); return false; } @@ -484,9 +564,10 @@ { Transparency |= IE_VVC_BLENDED; - for(unsigned int i=0;i<3;i++) { + for(unsigned int i=0;i<3*MAX_ORIENT;i++) { if (anims[i]) { - PrepareAnimation(anims[i], palettes[i], IE_VVC_BLENDED); + //don't call mirror again + PrepareAnimation(anims[i], IE_VVC_BLENDED); } } if (twin) { @@ -494,18 +575,26 @@ } } -void ScriptedAnimation::AlterPalette(const RGBModifier& mod) +void ScriptedAnimation::GetPaletteCopy() { - for(unsigned int i=0;i<3;i++) { + if (palette) + return; + for (unsigned int i=0;i<3*MAX_ORIENT;i++) { if (anims[i]) { - if (!palettes[i]) { - Sprite2D* spr = anims[i]->GetFrame(0); - if (!spr) return; - palettes[i] = core->GetVideoDriver()->GetPalette(spr)->Copy(); + Sprite2D* spr = anims[i]->GetFrame(0); + if (spr) { + palette = core->GetVideoDriver()->GetPalette(spr)->Copy(); } - palettes[i]->SetupCompleteRGBModification(palettes[i],mod); } } +} + +void ScriptedAnimation::AlterPalette(const RGBModifier& mod) +{ + GetPaletteCopy(); + if (!palette) + return; + palette->SetupCompleteRGBModification(palette,mod); if (twin) { twin->AlterPalette(mod); } @@ -518,7 +607,7 @@ } ScriptedAnimation * ret = twin; ret->YPos+=ret->ZPos+1; - ret->ZPos=-1; - twin=NULL; + ret->ZPos=-1; + twin=NULL; return ret; } Modified: gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.h 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.h 2007-04-07 00:39:21 UTC (rev 4572) @@ -50,12 +50,15 @@ ~ScriptedAnimation(void); ScriptedAnimation(DataStream* stream, bool autoFree = true); void Init(); - void LoadAnimationFactory(AnimationFactory *af, bool gettwin = false); + void LoadAnimationFactory(AnimationFactory *af, int gettwin = 0); void Override(ScriptedAnimation *templ); //there are 3 phases: start, hold, release //it will usually cycle in the 2. phase - Animation* anims[3]; - Palette *palettes[3]; + //the anims could also be used 'orientation based' if FaceTarget is + //set to 5, 9, 16 + Animation* anims[3*MAX_ORIENT]; + //there is only one palette + Palette *palette; ieResRef sounds[3]; ieResRef PaletteName; ieDword Transparency; @@ -65,6 +68,7 @@ int XPos, YPos, ZPos; ieDword FrameRate; ieDword FaceTarget; + unsigned char Orientation, NewOrientation; ieDword Duration; bool justCreated; ieResRef ResName; @@ -73,7 +77,7 @@ ScriptedAnimation *twin; public: //draws the next frame of the videocell - bool Draw(Region &screen, Point &Pos, Color &tint, Map *area, int dither); + bool Draw(Region &screen, Point &Pos, Color &tint, Map *area, int dither, int orientation); //sets phase (0-2) void SetPhase(int arg); //sets sound for phase (p_onset, p_hold, p_release) @@ -93,6 +97,8 @@ ieDword GetSequenceDuration(ieDword multiplier); /* sets default duration if it wasn't set yet */ void SetDefaultDuration(unsigned int duration); + /* sets up the direction of the vvc */ + void SetOrientation(int orientation); /* transforms vvc to blended */ void SetBlend(); /* alters palette with rgb factor */ @@ -100,7 +106,9 @@ /* returns possible twin after altering it to become underlay */ ScriptedAnimation *DetachTwin(); private: - void PrepareAnimation(Animation *anim, Palette *&palette, ieDword Transparency); + void PrepareAnimation(Animation *anim, ieDword Transparency); + bool HandlePhase(Sprite2D *&frame); + void GetPaletteCopy(); }; #endif Modified: gemrb/trunk/gemrb/plugins/Core/Spell.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spell.cpp 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/Spell.cpp 2007-04-07 00:39:21 UTC (rev 4572) @@ -21,6 +21,8 @@ #include "../../includes/win32def.h" #include "Spell.h" +#include "Projectile.h" +#include "ProjectileServer.h" #include "Interface.h" SPLExtHeader::SPLExtHeader(void) @@ -40,18 +42,12 @@ Spell::~Spell(void) { core->FreeSPLExt(ext_headers, casting_features); -/* - if (SpellIconBAM) { - core->FreeInterface( SpellIconBAM ); - SpellIconBAM = NULL; - } -*/ } //-1 will return cfb //0 will always return first spell block //otherwise set to caster level -EffectQueue *Spell::GetEffectBlock(int level) +EffectQueue *Spell::GetEffectBlock(int level) const { Effect *features; int count; @@ -90,3 +86,16 @@ } return fxqueue; } + +Projectile *Spell::GetProjectile(int header) const +{ + SPLExtHeader *eh = GetExtHeader(header); + if (!eh) { + return NULL; + } + EffectQueue *fx = GetEffectBlock(header); + Projectile *pro = core->GetProjectileServer()->GetProjectileByIndex(eh->ProjectileAnimation); + pro->SetEffects(fx); + return pro; +} + Modified: gemrb/trunk/gemrb/plugins/Core/Spell.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spell.h 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/Spell.h 2007-04-07 00:39:21 UTC (rev 4572) @@ -34,6 +34,8 @@ #include "AnimationMgr.h" #include "EffectQueue.h" +class Projectile; + #ifdef WIN32 #ifdef GEM_BUILD_DLL @@ -85,7 +87,7 @@ ieWord FeatureOffset; ieWord Charges; ieWord ChargeDepletion; - ieWord Projectile; + ieWord ProjectileAnimation; Effect* features; }; @@ -143,8 +145,18 @@ char unknown13[8]; public: + //returns the requested extended header + SPLExtHeader *GetExtHeader(unsigned int which) const + { + if(ExtHeaderCount<=which) { + return NULL; + } + return ext_headers+which; + } //-1 will return the cfb - EffectQueue *GetEffectBlock(int wanted_level); + EffectQueue *GetEffectBlock(int wanted_level) const; + //returns a projectile created from an extended header + Projectile *GetProjectile(int header) const; }; #endif // ! SPELL_H Modified: gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp 2007-04-07 00:39:21 UTC (rev 4572) @@ -24,6 +24,7 @@ #include "Spell.h" #include "TableMgr.h" #include "Actor.h" +#include "Projectile.h" static ieResRef *spelllist = NULL; static ieResRef *innatelist = NULL; @@ -582,7 +583,7 @@ array[pos].Target = ext_header->Target; array[pos].TargetNumber = ext_header->TargetNumber; array[pos].Range = ext_header->Range; - array[pos].Projectile = ext_header->Projectile; + array[pos].Projectile = ext_header->ProjectileAnimation; array[pos].CastingTime = (ieWord) ext_header->CastingTime; array[pos].strref = spl->SpellName; array[pos].count = 1; @@ -596,21 +597,6 @@ return false; } -bool Spellbook::CastSpell( ieResRef SpellResRef, Actor* Source, Actor* Target ) -{ - if (! HaveSpell( SpellResRef, HS_DEPLETE )) { - return false; - } - - Spell* spl = core->GetSpell( SpellResRef ); - for (int i = 0; i < spl->CastingFeatureCount; i++) { - Effect* fx = &spl->casting_features[i]; - AddEffect( fx, Source, Target ); - } - - return true; -} - void Spellbook::dump() { unsigned int k; Modified: gemrb/trunk/gemrb/plugins/Core/Spellbook.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spellbook.h 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/Core/Spellbook.h 2007-04-07 00:39:21 UTC (rev 4572) @@ -195,10 +195,6 @@ /** lists spells of a type */ bool GetSpellInfo(SpellExtHeader *array, int type, int startindex, int count); - - /** applies the spell on target */ - bool CastSpell( ieResRef SpellResRef, Actor* Source, Actor* Target ); - /** Dumps spellbook to stdout for debugging */ void dump(); }; Modified: gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-04-07 00:39:21 UTC (rev 4572) @@ -249,7 +249,7 @@ //b5 //unknown //b6 //unknown //b7 //unknown -int fx_dontjump_modifier (Actor* Owner, Actor* target, Effect* fx);//b8 +int fx_dontjump_modifier (Actor* Owner, Actor* target, Effect* fx);//b8 // this function is exactly the same as 0xaf hold_creature (in bg2 at least) //b9 int fx_move_to_area (Actor* Owner, Actor* target, Effect* fx);//ba int fx_local_variable (Actor* Owner, Actor* target, Effect* fx);//bb @@ -294,7 +294,7 @@ //e2 decrementing secondary type immunity (fx_generic_decrement_effect) int fx_bounce_school_dec (Actor* Owner, Actor* target, Effect* fx);//e3 int fx_bounce_secondary_type_dec (Actor* Owner, Actor* target, Effect* fx);//e4 -int fx_dispel_school_one (Actor* Owner, Actor* target, Effect* fx);//e5 +int fx_dispel_school_one (Actor* Owner, Actor* target, Effect* fx);//e5 int fx_dispel_secondary_type_one (Actor* Owner, Actor* target, Effect* fx);//e6 int fx_timestop (Actor* Owner, Actor* target, Effect* fx);//e7 int fx_cast_spell_on_condition (Actor* Owner, Actor* target, Effect* fx);//e8 @@ -448,7 +448,7 @@ { "Color:SetRGB", fx_set_color_rgb, 0 }, { "Color:PulseRGB", fx_set_color_pulse_rgb, 0 }, //8 { "ConstitutionModifier", fx_constitution_modifier, 0 }, - { "ControlCreature", fx_set_charmed_state, 0 }, //0xf1 same as charm + { "ControlCreature", fx_set_charmed_state, 0 }, //0xf1 same as charm { "CreateContingency", fx_create_contingency, 0 }, { "CriticalHitModifier", fx_critical_hit_modifier, 0 }, { "CrushingResistanceModifier", fx_crushing_resistance_modifier, 0 }, @@ -744,35 +744,35 @@ int a, stat; switch (table) { - case 2: //EA - stat = IE_EA; break; - case 3: //GENERAL - stat = IE_GENERAL; break; - case 4: //RACE - stat = IE_RACE; break; - case 5: //CLASS - stat = IE_CLASS; break; - case 6: //SPECIFIC - stat = IE_SPECIFIC; break; - case 7: //GENDER - stat = IE_SEX; break; - case 8: //ALIGNMENT - stat = target->GetStat(IE_ALIGNMENT); - a = value&15; - if (a) { - if (a != ( stat & 15 )) { - return false; - } + case 2: //EA + stat = IE_EA; break; + case 3: //GENERAL + stat = IE_GENERAL; break; + case 4: //RACE + stat = IE_RACE; break; + case 5: //CLASS + stat = IE_CLASS; break; + case 6: //SPECIFIC + stat = IE_SPECIFIC; break; + case 7: //GENDER + stat = IE_SEX; break; + case 8: //ALIGNMENT + stat = target->GetStat(IE_ALIGNMENT); + a = value&15; + if (a) { + if (a != ( stat & 15 )) { + return false; } - a = value & 240; - if (a) { - if (a != ( stat & 240 )) { - return false; - } + } + a = value & 240; + if (a) { + if (a != ( stat & 240 )) { + return false; } - return true; - default: - return false; + } + return true; + default: + return false; } if (target->GetStat(stat)==value) { return true; @@ -1117,7 +1117,7 @@ case 0: //normal haste if ( STATE_GET(STATE_SLOWED) ) { BASE_STATE_CURE( STATE_SLOWED ); - target->fxqueue.RemoveAllEffects( fx_set_slow_state_ref ); + target->fxqueue.RemoveAllEffects(fx_set_slow_state_ref); target->fxqueue.RemoveAllEffectsWithParam( fx_display_portrait_icon_ref, PI_SLOWED ); } else { BASE_STATE_SET( STATE_HASTED ); @@ -1126,7 +1126,7 @@ case 1://improved haste if ( STATE_GET(STATE_SLOWED) ) { BASE_STATE_CURE( STATE_SLOWED ); - target->fxqueue.RemoveAllEffects( fx_set_slow_state_ref ); + target->fxqueue.RemoveAllEffects(fx_set_slow_state_ref); target->fxqueue.RemoveAllEffectsWithParam( fx_display_portrait_icon_ref, PI_SLOWED ); } else { BASE_STATE_SET( STATE_HASTED ); @@ -1233,14 +1233,14 @@ int fx_set_invisible_state (Actor* /*Owner*/, Actor* target, Effect* fx) { switch (fx->Parameter2) { - case 0: - STATE_SET( STATE_INVISIBLE ); - break; - case 1: - STATE_SET( STATE_INVIS2 ); - break; - default: - break; + case 0: + STATE_SET( STATE_INVISIBLE ); + break; + case 1: + STATE_SET( STATE_INVIS2 ); + break; + default: + break; } ieDword Trans = fx->Parameter4; if (fx->Parameter3) { @@ -1322,8 +1322,7 @@ //also this effect is executed every update ieDword damage; - switch(fx->Parameter2) - { + switch(fx->Parameter2) { case RPD_PERCENT: damage = target->GetStat(IE_MAXHITPOINTS) * fx->Parameter1 / 100; break; @@ -1345,7 +1344,6 @@ return FX_APPLIED; } - // 0x1a EffectRef fx_apply_effect_curse_ref={"ApplyEffectCurse",NULL,-1}; @@ -1511,7 +1509,7 @@ if (0) printf( "fx_set_slowed_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (STATE_GET(STATE_HASTED) ) { BASE_STATE_CURE( STATE_HASTED ); - target->fxqueue.RemoveAllEffects( fx_set_haste_state_ref ); + target->fxqueue.RemoveAllEffects( fx_set_haste_state_ref ); target->fxqueue.RemoveAllEffectsWithParam( fx_display_portrait_icon_ref, PI_HASTED ); } else { STATE_SET( STATE_SLOWED ); @@ -1768,20 +1766,20 @@ ieDword level; switch (fx->Parameter2) { - case 0: - default: - level = 0xffffffff; - break; - case 1: - //same level: 50% success, each diff modifies it by 5% - level = core->Roll(1,20,fx->Power-10); - if (level>0x80000000) level = 0; - break; - case 2: - //same level: 50% success, each diff modifies it by 5% - level = core->Roll(1,20,fx->Parameter1-10); - if (level>0x80000000) level = 0; - break; + case 0: + default: + level = 0xffffffff; + break; + case 1: + //same level: 50% success, each diff modifies it by 5% + level = core->Roll(1,20,fx->Power-10); + if (level>0x80000000) level = 0; + break; + case 2: + //same level: 50% success, each diff modifies it by 5% + level = core->Roll(1,20,fx->Parameter1-10); + if (level>0x80000000) level = 0; + break; } target->fxqueue.RemoveLevelEffects(level, RL_DISPELLABLE, 0); return FX_NOT_APPLIED; @@ -1802,23 +1800,23 @@ if (0) printf( "fx_miscast_magic_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); switch (fx->Parameter2) { - case 3: - STAT_SET( IE_DEADMAGIC, 1); - case 0: - STAT_SET( IE_SPELLFAILUREMAGE, fx->Parameter1); - break; - case 4: - STAT_SET( IE_DEADMAGIC, 1); - case 1: - STAT_SET( IE_SPELLFAILUREPRIEST, fx->Parameter1); - break; - case 5: - STAT_SET( IE_DEADMAGIC, 1); - case 2: - STAT_SET( IE_SPELLFAILUREINNATE, fx->Parameter1); - break; - default: - return FX_NOT_APPLIED; + case 3: + STAT_SET( IE_DEADMAGIC, 1); + case 0: + STAT_SET( IE_SPELLFAILUREMAGE, fx->Parameter1); + break; + case 4: + STAT_SET( IE_DEADMAGIC, 1); + case 1: + STAT_SET( IE_SPELLFAILUREPRIEST, fx->Parameter1); + break; + case 5: + STAT_SET( IE_DEADMAGIC, 1); + case 2: + STAT_SET( IE_SPELLFAILUREINNATE, fx->Parameter1); + break; + default: + return FX_NOT_APPLIED; } return FX_APPLIED; } @@ -2085,8 +2083,7 @@ //setting damage to 0 because not all types do damage ieDword damage = 0; - switch(fx->Parameter2) - { + switch(fx->Parameter2) { case RPD_PERCENT: damage = target->GetStat(IE_MAXHITPOINTS) * fx->Parameter1 / 100; break; @@ -2318,8 +2315,7 @@ if (0) printf( "fx_set_regenerating_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); int damage; - switch(fx->Parameter2) - { + switch(fx->Parameter2) { case RPD_PERCENT: damage = target->GetStat(IE_MAXHITPOINTS) * fx->Parameter1 / 100; break; @@ -2814,7 +2810,7 @@ } if (fx->Parameter2<(ieDword) cgcount) { - ScriptedAnimation *sca = core->GetScriptedAnimation(casting_glows[fx->Parameter2]); + ScriptedAnimation *sca = core->GetScriptedAnimation(casting_glows[fx->Parameter2], false); if (!sca) { return FX_NOT_APPLIED; } @@ -2848,7 +2844,7 @@ return FX_APPLIED; } if (fx->Parameter2<(ieDword) shcount) { - ScriptedAnimation *sca = core->GetScriptedAnimation(spell_hits[fx->Parameter2]); + ScriptedAnimation *sca = core->GetScriptedAnimation(spell_hits[fx->Parameter2], false); if (!sca) { return FX_NOT_APPLIED; } @@ -2926,7 +2922,7 @@ { if (0) printf( "fx_learn_spell (%2d): Resource:%s Mode: %d\n", fx->Opcode, fx->Resource, fx->Parameter1 ); //parameter1 is unused, gemrb lets you to make it not give XP - //probably we should also let this via a game flag if we want + //probably we should also let this via a game flag if we want //full compatibility with bg1 target->LearnSpell(fx->Resource, fx->Parameter1^LS_ADDXP); return FX_NOT_APPLIED; @@ -2985,8 +2981,7 @@ Point p(fx->PosX, fx->PosY); //remove old creature - switch(fx->Parameter2) - { + switch(fx->Parameter2) { case 0: //remove silently target->DestroySelf(); break; @@ -3016,7 +3011,7 @@ { if (0) printf( "fx_set_sanctuary_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_SET( IE_SANCTUARY, 1); - return FX_APPLIED; + return FX_APPLIED; } // 0x9a Overlay:Entangle @@ -3025,7 +3020,7 @@ if (0) printf( "fx_set_entangle_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_SET( IE_ENTANGLE, 1); //STAT_SET(IE_MOVEMENTRATE, 0); // - return FX_APPLIED; + return FX_APPLIED; } // 0x9b Overlay:MinorGlobe @@ -3033,7 +3028,7 @@ { if (0) printf( "fx_set_minorglobe_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_SET( IE_MINORGLOBE, 1); - return FX_APPLIED; + return FX_APPLIED; } // 0x9c Overlay:ShieldGlobe @@ -3041,7 +3036,7 @@ { if (0) printf( "fx_set_shieldglobe_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_SET( IE_SHIELDGLOBE, 1); - return FX_APPLIED; + return FX_APPLIED; } // 0x9d Overlay:Web @@ -3050,7 +3045,7 @@ if (0) printf( "fx_set_web_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_SET( IE_WEB, 1); STAT_SET(IE_MOVEMENTRATE, 0); // - return FX_APPLIED; + return FX_APPLIED; } // 0x9e Overlay:Grease @@ -3059,7 +3054,7 @@ if (0) printf( "fx_set_grease_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_SET( IE_GREASE, 1); STAT_SET(IE_MOVEMENTRATE, 3); // - return FX_APPLIED; + return FX_APPLIED; } // 0x9f MirrorImageModifier @@ -3107,7 +3102,7 @@ { if (0) printf( "fx_cure_hold_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //note that this effect doesn't remove 185 (another hold effect) - target->fxqueue.RemoveAllEffects( fx_hold_creature_ref ); + target->fxqueue.RemoveAllEffects( fx_hold_creature_ref ); return FX_NOT_APPLIED; } @@ -3117,7 +3112,7 @@ int fx_cure_slow_state (Actor* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_cure_slow_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - target->fxqueue.RemoveAllEffects( fx_movement_modifier_ref ); + target->fxqueue.RemoveAllEffects( fx_movement_modifier_ref ); // STATE_CURE( STATE_SLOWED ); return FX_NOT_APPLIED; } @@ -3192,8 +3187,7 @@ int fx_remove_spell (Actor* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_remove_spell (%2d): Resource: %s Type:%d\n", fx->Opcode, fx->Resource, fx->Parameter2); - switch (fx->Parameter2) - { + switch (fx->Parameter2) { default: target->spellbook.RemoveSpell(fx->Resource); break; @@ -3381,7 +3375,7 @@ core->SummonCreature(fx->Resource, fx->Resource2, Owner, target, p, -1,0); return FX_NOT_APPLIED; } -// 0xc1 InvisibleDetection +// 0xc1 InvisibleDetection int fx_see_invisible_modifier (Actor* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_see_invisible_modifier (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 ); @@ -3580,7 +3574,7 @@ { if (0) printf( "fx_play_visual_effect (%2d): Resource: %s Type: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 ); if (fx->Resource[0]) { - ScriptedAnimation* vvc = core->GetScriptedAnimation(fx->Resource); + ScriptedAnimation* vvc = core->GetScriptedAnimation(fx->Resource, false); if (fx->Parameter2) { //play over target target->AddVVCell( vvc ); @@ -3727,8 +3721,7 @@ //get subject of check Actor *actor = NULL; Map *map = target->GetCurrentArea(); - switch(fx->Parameter1) - { + switch(fx->Parameter1) { //self case 0: actor = target; break; //last attacker @@ -3743,8 +3736,7 @@ } int condition; //check condition - switch(fx->Parameter2) - { + switch(fx->Parameter2) { case COND_GOTHIT: //on hit condition = target->LastDamage; break; @@ -3912,7 +3904,7 @@ { if (0) printf( "fx_drain_spells (%2d): Count: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); ieDword i=fx->Parameter1; - if (fx->Parameter2) + if (fx->Parameter2) while(i--) { if (!target->spellbook.DepleteSpell(IE_SPELL_TYPE_WIZARD)) { break; Modified: gemrb/trunk/gemrb/plugins/IWDOpcodes/IWDOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/IWDOpcodes/IWDOpc.cpp 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/IWDOpcodes/IWDOpc.cpp 2007-04-07 00:39:21 UTC (rev 4572) @@ -369,7 +369,7 @@ return FX_APPLIED; } if (fx->Parameter2<(ieDword) shcount) { - ScriptedAnimation *sca = core->GetScriptedAnimation(iwd_spell_hits[fx->Parameter2]); + ScriptedAnimation *sca = core->GetScriptedAnimation(iwd_spell_hits[fx->Parameter2], false); if (!sca) { return FX_NOT_APPLIED; } Modified: gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-07 00:39:21 UTC (rev 4572) @@ -33,6 +33,7 @@ int fx_set_status (Actor* Owner, Actor* target, Effect* fx);//ba int fx_play_bam_bb (Actor* Owner, Actor* target, Effect* fx);//bb int fx_play_bam (Actor* Owner, Actor* target, Effect* fx);//bc,bd,be,bf +int fx_play_bam_bf (Actor* Owner, Actor* target, Effect* fx);//bf int fx_transfer_hp (Actor* Owner, Actor* target, Effect* fx);//c0 //int fx_shake_screen (Actor* Owner, Actor* target, Effect* fx);//c1 already implemented int fx_flash_screen (Actor* Owner, Actor* target, Effect* fx);//c2 @@ -67,7 +68,7 @@ { "PlayBAM2", fx_play_bam, 0},//bc,bd,be,bf { "PlayBAM3", fx_play_bam, 0}, { "PlayBAM4", fx_play_bam, 0}, - { "PlayBAM5", fx_play_bam, 0}, + { "PlayBAM5", fx_play_bam_bf, 0}, { "Prayer", fx_prayer, 0},//cc { "SetStatus", fx_set_status, 0}, //ba { "SpecialEffect", fx_special_effect, 0},//c4 @@ -99,14 +100,14 @@ } //bb fx_play_bam_bb (play blended animation) -int fx_play_bam_bb (Actor* /*Owner*/, Actor* target, Effect* fx) +int fx_play_bam_bb (Actor* Owner, Actor* target, Effect* fx) { bool playonce; if (0) printf( "fx_play_bam_bb (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); //play once set to true //check tearring.itm (0xbb effect) - ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource); + ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource, true); if (!sca) return FX_NOT_APPLIED; @@ -141,9 +142,8 @@ } if (fx->Parameter2&2) { sca->XPos+=fx->PosX; - sca->YPos+=fx->PosY; - //probably we should use Owner? - target->GetCurrentArea()->AddVVCell(sca); + sca->YPos+=fx->PosY; + Owner->GetCurrentArea()->AddVVCell(sca); } else { ScriptedAnimation *twin = sca->DetachTwin(); if (twin) { @@ -156,14 +156,14 @@ //bc,bd,be,bf fx_play_bam //these are not yet fully implemented -int fx_play_bam (Actor* /*Owner*/, Actor* target, Effect* fx) +int fx_play_bam (Actor* Owner, Actor* target, Effect* fx) { bool playonce; if (0) printf( "fx_play_bam (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); //play once set to true //check tearring.itm (0xbb effect) - ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource); + ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource, false); if (!sca) return FX_NOT_APPLIED; if (fx->Parameter1) { @@ -197,13 +197,65 @@ if (fx->Parameter2&2) { sca->XPos+=fx->PosX; sca->YPos+=fx->PosY; - target->GetCurrentArea()->AddVVCell(sca); + Owner->GetCurrentArea()->AddVVCell(sca); } else { target->AddVVCell(sca); } return FX_NOT_APPLIED; } +int fx_play_bam_bf (Actor* Owner, Actor* target, Effect* fx) +{ + bool playonce; + + if (0) printf( "fx_play_bam (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); + //play once set to true + //check tearring.itm (0xbb effect) + ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource, true); + if (!sca) + return FX_NOT_APPLIED; + if (fx->Parameter1) { + RGBModifier rgb; + + rgb.speed=-1; + rgb.phase=0; + rgb.rgb.r=fx->Parameter1; + rgb.rgb.g=fx->Parameter1 >> 8; + rgb.rgb.b=fx->Parameter1 >> 16; + rgb.rgb.a=fx->Parameter1 >> 24; + rgb.type=RGBModifier::TINT; + sca->AlterPalette(rgb); + } + if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { + playonce=true; + } else { + playonce=false; + } + if (fx->Parameter2&1) { + //four cycles, duration is in millisecond + sca->SetDefaultDuration(sca->GetSequenceDuration(4000)); + } else { + if (playonce) { + sca->PlayOnce(); + } else { + sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks); + } + } + sca->SetBlend(); + if (fx->Parameter2&2) { + sca->XPos+=fx->PosX; + sca->YPos+=fx->PosY; + Owner->GetCurrentArea()->AddVVCell(sca); + } else { + ScriptedAnimation *twin = sca->DetachTwin(); + if (twin) { + target->AddVVCell(twin); + } + target->AddVVCell(sca); + } + return FX_NOT_APPLIED; +} + //0xc0 fx_transfer_hp int fx_transfer_hp (Actor* Owner, Actor* target, Effect* fx) { Modified: gemrb/trunk/gemrb/plugins/SPLImporter/SPLImp.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/SPLImporter/SPLImp.cpp 2007-04-06 23:56:28 UTC (rev 4571) +++ gemrb/trunk/gemrb/plugins/SPLImporter/SPLImp.cpp 2007-04-07 00:39:21 UTC (rev 4572) @@ -159,7 +159,7 @@ str->ReadWord( &eh->FeatureOffset ); str->ReadWord( &eh->Charges ); str->ReadWord( &eh->ChargeDepletion ); - str->ReadWord( &eh->Projectile ); + str->ReadWord( &eh->ProjectileAnimation ); eh->features = core->GetFeatures( eh->FeatureCount ); str->Seek( s->FeatureBlockOffset + 48*eh->FeatureOffset, GEM_STREAM_START ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-04-08 08:42:20
|
Revision: 4578 http://gemrb.svn.sourceforge.net/gemrb/?rev=4578&view=rev Author: avenger_teambg Date: 2007-04-08 01:42:18 -0700 (Sun, 08 Apr 2007) Log Message: ----------- improved vvc handling (per surface transparency) pst:added iterations to SinisterPoof action Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Actions.cpp gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp gemrb/trunk/gemrb/plugins/Core/GSUtils.h gemrb/trunk/gemrb/plugins/Core/GameScript.cpp gemrb/trunk/gemrb/plugins/Core/GameScript.h gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.h gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp Modified: gemrb/trunk/gemrb/plugins/Core/Actions.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-04-08 07:44:18 UTC (rev 4577) +++ gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-04-08 08:42:18 UTC (rev 4578) @@ -528,7 +528,7 @@ Area[0]=0; } if (parameters->string0Parameter[0]) { - CreateVisualEffectCore(Sender, Sender->Pos, parameters->string0Parameter); + CreateVisualEffectCore(Sender, Sender->Pos, parameters->string0Parameter, 0); } MoveBetweenAreasCore( (Actor *) Sender, Area, tar->Pos, -1, true); } @@ -1470,18 +1470,34 @@ { } +// creates area vvc at position of object void GameScript::CreateVisualEffectObject(Scriptable* Sender, Action* parameters) { Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); if (!tar) { return; } - CreateVisualEffectCore(tar, tar->Pos, parameters->string0Parameter); + CreateVisualEffectCore(tar, tar->Pos, parameters->string0Parameter, parameters->int0Parameter); } +// creates sticky vvc on actor or normal animation on object +void GameScript::CreateVisualEffectObjectSticky(Scriptable* Sender, Action* parameters) +{ + Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); + if (!tar) { + return; + } + if (tar->Type==ST_ACTOR) { + CreateVisualEffectCore((Actor *) tar, parameters->string0Parameter, parameters->int0Parameter); + } else { + CreateVisualEffectCore(tar, tar->Pos, parameters->string0Parameter, parameters->int0Parameter); + } +} + +// creates area effect at point void GameScript::CreateVisualEffect(Scriptable* Sender, Action* parameters) { - CreateVisualEffectCore(Sender, parameters->pointParameter, parameters->string0Parameter); + CreateVisualEffectCore(Sender, parameters->pointParameter, parameters->string0Parameter, parameters->int0Parameter); } void GameScript::DestroySelf(Scriptable* Sender, Action* /*parameters*/) @@ -2049,7 +2065,7 @@ return; } if (parameters->string1Parameter[0]) { - CreateVisualEffectCore(Sender, Sender->Pos, parameters->string1Parameter); + CreateVisualEffectCore(Sender, Sender->Pos, parameters->string1Parameter, 0); } MoveBetweenAreasCore((Actor *) Sender, parameters->string0Parameter, parameters->pointParameter, parameters->int0Parameter, true); Modified: gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp 2007-04-08 07:44:18 UTC (rev 4577) +++ gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp 2007-04-08 08:42:18 UTC (rev 4578) @@ -674,7 +674,7 @@ //if string1 is animation, then we can't use it for a DV too if (flags & CC_PLAY_ANIM) { - CreateVisualEffectCore( ab, ab->Pos, parameters->string1Parameter); + CreateVisualEffectCore( ab, ab->Pos, parameters->string1Parameter, 1); } else { //setting the deathvariable if it exists (iwd2) if (parameters->string1Parameter[0]) { @@ -689,16 +689,34 @@ } } -void CreateVisualEffectCore(Scriptable *Sender, Point &position, const char *effect) +static ScriptedAnimation *GetVVCEffect(const char *effect, int iterations) { -//TODO: add engine specific VVC replacement methods -//stick to object flag, sounds, iterations etc. if (effect[0]) { ScriptedAnimation* vvc = core->GetScriptedAnimation(effect, false); if (!vvc) { printMessage("GameScript","Failed to create effect.",LIGHT_RED); - return; + return NULL; } + if (iterations) { + vvc->SetDefaultDuration( vvc->GetSequenceDuration(1000 * iterations)); + } + return vvc; + } + return NULL; +} + +void CreateVisualEffectCore(Actor *target, const char *effect, int iterations) +{ + ScriptedAnimation *vvc = GetVVCEffect(effect, iterations); + if (vvc) { + target->AddVVCell( vvc ); + } +} + +void CreateVisualEffectCore(Scriptable *Sender, Point &position, const char *effect, int iterations) +{ + ScriptedAnimation *vvc = GetVVCEffect(effect, iterations); + if (vvc) { vvc->XPos +=position.x; vvc->YPos +=position.y; Sender->GetCurrentArea( )->AddVVCell( vvc ); @@ -717,7 +735,7 @@ tar->SetOrientation(src->GetOrientation(), false ); src->DestroySelf(); if (effect) { - CreateVisualEffectCore(tar, tar->Pos,"smokepuffeffect"); + CreateVisualEffectCore(tar, tar->Pos,"smokepuffeffect",1); } } } Modified: gemrb/trunk/gemrb/plugins/Core/GSUtils.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GSUtils.h 2007-04-08 07:44:18 UTC (rev 4577) +++ gemrb/trunk/gemrb/plugins/Core/GSUtils.h 2007-04-08 08:42:18 UTC (rev 4578) @@ -46,7 +46,8 @@ bool HasItemCore(Inventory *inventory, ieResRef itemname, ieDword flags); void ClickCore(Point &point, int type, int speed); void TransformItemCore(Actor *actor, Action *parameters, bool onlyone); -void CreateVisualEffectCore(Scriptable *Sender, Point &position, const char *effect); +void CreateVisualEffectCore(Actor *target, const char *effect, int iterations); +void CreateVisualEffectCore(Scriptable *Sender, Point &position, const char *effect, int iterations); void GetPositionFromScriptable(Scriptable* scr, Point &position, bool trap); int CanSee(Scriptable* Sender, Scriptable* target, bool range, int nodead); void BeginDialog(Scriptable* Sender, Action* parameters, int flags); Modified: gemrb/trunk/gemrb/plugins/Core/GameScript.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameScript.cpp 2007-04-08 07:44:18 UTC (rev 4577) +++ gemrb/trunk/gemrb/plugins/Core/GameScript.cpp 2007-04-08 08:42:18 UTC (rev 4578) @@ -461,6 +461,7 @@ {"createpartygold", GameScript::CreatePartyGold, 0}, {"createvisualeffect", GameScript::CreateVisualEffect, 0}, {"createvisualeffectobject", GameScript::CreateVisualEffectObject, 0}, + {"createvisualeffectobjectSticky", GameScript::CreateVisualEffectObjectSticky, 0}, {"cutsceneid", GameScript::CutSceneID,AF_INSTANT}, {"damage", GameScript::Damage, 0}, {"daynight", GameScript::DayNight, 0}, @@ -821,7 +822,7 @@ {"staticsequence", GameScript::PlaySequence, 0},//bg2 animation sequence {"staticstart", GameScript::StaticStart, 0}, {"staticstop", GameScript::StaticStop, 0}, - {"stickysinisterpoof", GameScript::CreateVisualEffectObject, 0}, + {"stickysinisterpoof", GameScript::CreateVisualEffectObjectSticky, 0}, {"stopmoving", GameScript::StopMoving, 0}, {"storepartylocations", GameScript::StorePartyLocation, 0}, {"swing", GameScript::Swing, 0}, Modified: gemrb/trunk/gemrb/plugins/Core/GameScript.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameScript.h 2007-04-08 07:44:18 UTC (rev 4577) +++ gemrb/trunk/gemrb/plugins/Core/GameScript.h 2007-04-08 08:42:18 UTC (rev 4578) @@ -1014,7 +1014,8 @@ static void CreateCreatureCopyPoint(Scriptable* Sender, Action* parameters); static void CreateCreatureDoor(Scriptable* Sender, Action* parameters); static void CreateCreatureImpassable(Scriptable* Sender, Action* parameters); - static void CreateCreatureImpassableAllowOverlap(Scriptable* Sender, Action* parameters); + static void CreateCreatureImpassableAllowOverlap(Scriptable* Sender, + Action* parameters); static void CreateCreatureObject(Scriptable* Sender, Action* parameters); static void CreateCreatureObjectCopy(Scriptable* Sender, Action* parameters); static void CreateCreatureObjectDoor(Scriptable* Sender, Action* parameters); @@ -1027,12 +1028,15 @@ static void CreateVisualEffect(Scriptable* Sender, Action* parameters); static void CreateVisualEffectObject(Scriptable* Sender, Action* parameters); + static void CreateVisualEffectObjectSticky(Scriptable* Sender, + Action* parameters); 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); - static void DestroyAllDestructableEquipment(Scriptable* Sender, Action* parameters); + static void DestroyAllDestructableEquipment(Scriptable* Sender, + Action* parameters); static void DestroyAllEquipment(Scriptable* Sender, Action* parameters); static void DestroyGold(Scriptable* Sender, Action* parameters); static void DestroyItem(Scriptable* Sender, Action* parameters); Modified: gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp 2007-04-08 07:44:18 UTC (rev 4577) +++ gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp 2007-04-08 08:42:18 UTC (rev 4578) @@ -68,14 +68,14 @@ sounds[0][0] = 0; sounds[1][0] = 0; sounds[2][0] = 0; - + memset(&Tint,0,sizeof(Tint)); Transparency = 0; SequenceFlags = 0; XPos = YPos = ZPos = 0; FrameRate = 15; FaceTarget = 0; Orientation = 0; - dither = 0; + Dither = 0; Duration = 0xffffffff; justCreated = true; PaletteName[0]=0; @@ -112,7 +112,7 @@ if (Transparency&IE_VVC_MIRRORY) { anim->MirrorAnimationVert(); } - + //make this the last if possible, because of the return if (Transparency&IE_VVC_BLENDED) { GetPaletteCopy(); @@ -184,7 +184,7 @@ c=SixteenToNine[c]; if ((i&15)>=9) mirror = true; } else p*=MAX_ORIENT; - + anims[p] = af->GetCycle( (ieByte) c ); if (anims[p]) { anims[p]->pos=0; @@ -241,7 +241,7 @@ delete( stream ); return; } - ieResRef Anim1ResRef; + ieResRef Anim1ResRef; ieDword seq1, seq2, seq3; stream->ReadResRef( Anim1ResRef ); //there is no proof it is a second resref @@ -290,7 +290,7 @@ anims[P_ONSET]->Flags |= S_ANI_PLAYONCE; } - anims[P_HOLD] = af->GetCycle( ( unsigned char ) seq2 ); + anims[P_HOLD] = af->GetCycle( ( unsigned char ) seq2 ); if (anims[P_HOLD]) { PrepareAnimation(anims[P_HOLD], Transparency); @@ -301,7 +301,7 @@ } } - anims[P_RELEASE] = af->GetCycle( ( unsigned char ) seq3 ); + anims[P_RELEASE] = af->GetCycle( ( unsigned char ) seq3 ); if (anims[P_RELEASE]) { PrepareAnimation(anims[P_RELEASE], Transparency); @@ -334,7 +334,7 @@ for(unsigned int i=0;i<3*MAX_ORIENT;i++) { if (anims[i]) { delete( anims[i] ); - } + } } core->FreePalette(palette, PaletteName); @@ -496,7 +496,7 @@ } //it is not sure if we need tint at all -bool ScriptedAnimation::Draw(Region &screen, Point &Pos, Color &p_tint, Map *area, int p_dither, int orientation) +bool ScriptedAnimation::Draw(Region &screen, Point &Pos, Color &p_tint, Map *area, int dither, int orientation) { if (FaceTarget) { SetOrientation(orientation); @@ -504,7 +504,7 @@ // not sure if (twin) { - twin->Draw(screen, Pos, p_tint, area, p_dither, -1); + twin->Draw(screen, Pos, p_tint, area, dither, -1); } Video *video = core->GetVideoDriver(); @@ -522,7 +522,7 @@ flag |= BLIT_HALFTRANS; } - Color tint = {0,0,0,0}; + Color tint = Tint; //darken, greyscale, red tint are probably not needed if the global tint works //these are used in the original engine to implement weather/daylight effects @@ -536,8 +536,11 @@ flag |= BLIT_RED; } + if (Transparency & BLIT_TINTED) { + flag |= BLIT_TINTED; + } + if ((Transparency & IE_VVC_TINT)==IE_VVC_TINT) { - flag |= BLIT_TINTED; tint = p_tint; } @@ -547,11 +550,11 @@ if( SequenceFlags&IE_VVC_NOCOVER) { if (cover) SetSpriteCover(NULL); } else { - if (!cover || (dither!=p_dither) || (!cover->Covers(cx, cy, frame->XPos, frame->YPos, frame->Width, frame->Height)) ) { - dither = p_dither; + if (!cover || (Dither!=dither) || (!cover->Covers(cx, cy, frame->XPos, frame->YPos, frame->Width, frame->Height)) ) { + Dither = dither; Animation *anim = anims[Phase*MAX_ORIENT+Orientation]; - SetSpriteCover(area->BuildSpriteCover(cx, cy, -anim->animArea.x, - -anim->animArea.y, anim->animArea.w, anim->animArea.h, p_dither) ); + SetSpriteCover(area->BuildSpriteCover(cx, cy, -anim->animArea.x, + -anim->animArea.y, anim->animArea.w, anim->animArea.h, dither) ); } assert(cover->Covers(cx, cy, frame->XPos, frame->YPos, frame->Width, frame->Height)); } @@ -575,6 +578,16 @@ } } +void ScriptedAnimation::SetFade(ieByte initial, int speed) +{ + Tint.r=255; + Tint.g=255; + Tint.b=255; + Tint.a=initial; + Fade=speed; + Transparency|=BLIT_TINTED; +} + void ScriptedAnimation::GetPaletteCopy() { if (palette) Modified: gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.h 2007-04-08 07:44:18 UTC (rev 4577) +++ gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.h 2007-04-08 08:42:18 UTC (rev 4578) @@ -61,9 +61,11 @@ Palette *palette; ieResRef sounds[3]; ieResRef PaletteName; + Color Tint; + int Fade; ieDword Transparency; ieDword SequenceFlags; - int dither; + int Dither; //these are signed int XPos, YPos, ZPos; ieDword FrameRate; @@ -101,6 +103,8 @@ void SetOrientation(int orientation); /* transforms vvc to blended */ void SetBlend(); + /* sets fade effect at end of animation (pst feature) */ + void SetFade(ieByte initial, int speed); /* alters palette with rgb factor */ void AlterPalette(const RGBModifier &rgb); /* returns possible twin after altering it to become underlay */ Modified: gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-08 07:44:18 UTC (rev 4577) +++ gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-08 08:42:18 UTC (rev 4578) @@ -32,7 +32,9 @@ int fx_set_status (Actor* Owner, Actor* target, Effect* fx);//ba int fx_play_bam_bb (Actor* Owner, Actor* target, Effect* fx);//bb -int fx_play_bam (Actor* Owner, Actor* target, Effect* fx);//bc,bd,be,bf +int fx_play_bam_bc (Actor* Owner, Actor* target, Effect* fx);//bc +int fx_play_bam_bd (Actor* Owner, Actor* target, Effect* fx);//bd +int fx_play_bam_be (Actor* Owner, Actor* target, Effect* fx);//be int fx_play_bam_bf (Actor* Owner, Actor* target, Effect* fx);//bf int fx_transfer_hp (Actor* Owner, Actor* target, Effect* fx);//c0 //int fx_shake_screen (Actor* Owner, Actor* target, Effect* fx);//c1 already implemented @@ -65,10 +67,10 @@ { "MoveView", fx_move_view, 0},//cd { "Overlay", fx_overlay, 0}, //c9 { "PlayBAM1", fx_play_bam_bb, 0}, //bb - { "PlayBAM2", fx_play_bam, 0},//bc,bd,be,bf - { "PlayBAM3", fx_play_bam, 0}, - { "PlayBAM4", fx_play_bam, 0}, - { "PlayBAM5", fx_play_bam_bf, 0}, + { "PlayBAM2", fx_play_bam_bc, 0},//bc + { "PlayBAM3", fx_play_bam_bd, 0}, //bd + { "PlayBAM4", fx_play_bam_be, 0}, //be + { "PlayBAM5", fx_play_bam_bf, 0}, //bf { "Prayer", fx_prayer, 0},//cc { "SetStatus", fx_set_status, 0}, //ba { "SpecialEffect", fx_special_effect, 0},//c4 @@ -99,7 +101,9 @@ return FX_NOT_APPLIED; } -//bb fx_play_bam_bb (play blended animation) +//bb fx_play_bam_bb (play multi-part blended sticky animation) +// 1 repeats +// 2 not sticky (override default) int fx_play_bam_bb (Actor* Owner, Actor* target, Effect* fx) { bool playonce; @@ -154,18 +158,66 @@ return FX_NOT_APPLIED; } -//bc,bd,be,bf fx_play_bam -//these are not yet fully implemented -int fx_play_bam (Actor* Owner, Actor* target, Effect* fx) +//bc play_bam_bc (play not blended single animation) +//sticky bit: 4096 +//transparency instead of rgb tint: 0x100000, fade off is in dice size +int fx_play_bam_bc (Actor* Owner, Actor* target, Effect* fx) { bool playonce; - if (0) printf( "fx_play_bam (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); + if (0) printf( "fx_play_bam_bc (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); //play once set to true //check tearring.itm (0xbb effect) ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource, false); if (!sca) return FX_NOT_APPLIED; + + if (fx->Parameter2&0x100000) { + sca->SetFade((ieByte) fx->Parameter1, fx->DiceSides); + } else { + if (fx->Parameter1) { + RGBModifier rgb; + + rgb.speed=-1; + rgb.phase=0; + rgb.rgb.r=fx->Parameter1; + rgb.rgb.g=fx->Parameter1 >> 8; + rgb.rgb.b=fx->Parameter1 >> 16; + rgb.rgb.a=fx->Parameter1 >> 24; + rgb.type=RGBModifier::TINT; + sca->AlterPalette(rgb); + } + } + if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { + playonce=true; + } else { + playonce=false; + } + if (playonce) { + sca->PlayOnce(); + } else { + sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks); + } + if (fx->Parameter2&4096) { + target->AddVVCell(sca); + } else { + sca->XPos+=fx->PosX; + sca->YPos+=fx->PosY; + Owner->GetCurrentArea()->AddVVCell(sca); + } + return FX_NOT_APPLIED; +} + +int fx_play_bam_bd (Actor* Owner, Actor* target, Effect* fx) +{ + bool playonce; + + if (0) printf( "fx_play_bam_bd (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); + //play once set to true + //check tearring.itm (0xbb effect) + ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource, false); + if (!sca) + return FX_NOT_APPLIED; if (fx->Parameter1) { RGBModifier rgb; @@ -204,11 +256,59 @@ return FX_NOT_APPLIED; } +int fx_play_bam_be (Actor* Owner, Actor* target, Effect* fx) +{ + bool playonce; + + if (0) printf( "fx_play_bam_be (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); + //play once set to true + //check tearring.itm (0xbb effect) + ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource, false); + if (!sca) + return FX_NOT_APPLIED; + if (fx->Parameter1) { + RGBModifier rgb; + + rgb.speed=-1; + rgb.phase=0; + rgb.rgb.r=fx->Parameter1; + rgb.rgb.g=fx->Parameter1 >> 8; + rgb.rgb.b=fx->Parameter1 >> 16; + rgb.rgb.a=fx->Parameter1 >> 24; + rgb.type=RGBModifier::TINT; + sca->AlterPalette(rgb); + } + if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { + playonce=true; + } else { + playonce=false; + } + if (fx->Parameter2&1) { + //four cycles, duration is in millisecond + sca->SetDefaultDuration(sca->GetSequenceDuration(4000)); + } else { + if (playonce) { + sca->PlayOnce(); + } else { + sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks); + } + } + sca->SetBlend(); + if (fx->Parameter2&2) { + sca->XPos+=fx->PosX; + sca->YPos+=fx->PosY; + Owner->GetCurrentArea()->AddVVCell(sca); + } else { + target->AddVVCell(sca); + } + return FX_NOT_APPLIED; +} + int fx_play_bam_bf (Actor* Owner, Actor* target, Effect* fx) { bool playonce; - if (0) printf( "fx_play_bam (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); + if (0) printf( "fx_play_bam_bf (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); //play once set to true //check tearring.itm (0xbb effect) ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource, true); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-04-09 05:52:40
|
Revision: 4581 http://gemrb.svn.sourceforge.net/gemrb/?rev=4581&view=rev Author: avenger_teambg Date: 2007-04-08 22:52:41 -0700 (Sun, 08 Apr 2007) Log Message: ----------- implemented fade/random placement play_bam options Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp Modified: gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp 2007-04-09 05:47:38 UTC (rev 4580) +++ gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp 2007-04-09 05:52:41 UTC (rev 4581) @@ -70,6 +70,7 @@ sounds[2][0] = 0; memset(&Tint,0,sizeof(Tint)); Transparency = 0; + Fade = 0; SequenceFlags = 0; XPos = YPos = ZPos = 0; FrameRate = 15; @@ -489,6 +490,14 @@ if (Phase>=P_RELEASE) { return true; } + //this section implements the freeze fading effect (see ice dagger) + if (frame && Fade && Tint.a && (Phase==P_HOLD) ) { + if (Tint.a<=Fade) { + return true; + } + Tint.a-=Fade; + return false; + } Phase++; goto retry; } @@ -619,8 +628,10 @@ return NULL; } ScriptedAnimation * ret = twin; - ret->YPos+=ret->ZPos+1; - ret->ZPos=-1; + //ret->YPos+=ret->ZPos+1; + if (ret->ZPos>=0) { + ret->ZPos=-1; + } twin=NULL; return ret; } Modified: gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-09 05:47:38 UTC (rev 4580) +++ gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-09 05:52:41 UTC (rev 4581) @@ -25,17 +25,13 @@ #include "../Core/Game.h" #include "../Core/EffectQueue.h" #include "../Core/Interface.h" -//#include "../Core/damages.h" #include "../Core/Video.h" //for tints #include "PSTOpc.h" int fx_set_status (Actor* Owner, Actor* target, Effect* fx);//ba -int fx_play_bam_bb (Actor* Owner, Actor* target, Effect* fx);//bb -int fx_play_bam_bc (Actor* Owner, Actor* target, Effect* fx);//bc -int fx_play_bam_bd (Actor* Owner, Actor* target, Effect* fx);//bd -int fx_play_bam_be (Actor* Owner, Actor* target, Effect* fx);//be -int fx_play_bam_bf (Actor* Owner, Actor* target, Effect* fx);//bf +int fx_play_bam_blended (Actor* Owner, Actor* target, Effect* fx);//bb +int fx_play_bam_not_blended (Actor* Owner, Actor* target, Effect* fx);//bc int fx_transfer_hp (Actor* Owner, Actor* target, Effect* fx);//c0 //int fx_shake_screen (Actor* Owner, Actor* target, Effect* fx);//c1 already implemented int fx_flash_screen (Actor* Owner, Actor* target, Effect* fx);//c2 @@ -66,11 +62,11 @@ { "JumbleCurse", fx_jumble_curse, 0}, //d3 { "MoveView", fx_move_view, 0},//cd { "Overlay", fx_overlay, 0}, //c9 - { "PlayBAM1", fx_play_bam_bb, 0}, //bb - { "PlayBAM2", fx_play_bam_bc, 0},//bc - { "PlayBAM3", fx_play_bam_bd, 0}, //bd - { "PlayBAM4", fx_play_bam_be, 0}, //be - { "PlayBAM5", fx_play_bam_bf, 0}, //bf + { "PlayBAM1", fx_play_bam_blended, 0}, //bb + { "PlayBAM2", fx_play_bam_not_blended, 0},//bc + { "PlayBAM3", fx_play_bam_not_blended, 0}, //bd + { "PlayBAM4", fx_play_bam_not_blended, 0}, //be + { "PlayBAM5", fx_play_bam_not_blended, 0}, //bf { "Prayer", fx_prayer, 0},//cc { "SetStatus", fx_set_status, 0}, //ba { "SpecialEffect", fx_special_effect, 0},//c4 @@ -104,11 +100,11 @@ //bb fx_play_bam_bb (play multi-part blended sticky animation) // 1 repeats // 2 not sticky (override default) -int fx_play_bam_bb (Actor* Owner, Actor* target, Effect* fx) +int fx_play_bam_blended (Actor* Owner, Actor* target, Effect* fx) { bool playonce; - if (0) printf( "fx_play_bam_bb (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); + if (0) printf( "fx_play_bam_blended (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); //play once set to true //check tearring.itm (0xbb effect) ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource, true); @@ -158,23 +154,43 @@ return FX_NOT_APPLIED; } -//bc play_bam_bc (play not blended single animation) +//bc-bf play_bam_not_blended (play not blended single animation) +//random placement (if not sticky): 1 //sticky bit: 4096 //transparency instead of rgb tint: 0x100000, fade off is in dice size -int fx_play_bam_bc (Actor* Owner, Actor* target, Effect* fx) +//blend: 0x300000 +//twin animation: 0x30000 +//background animation: 0x10000 +//foreground animation: 0x20000 +int fx_play_bam_not_blended (Actor* Owner, Actor* target, Effect* fx) { bool playonce; + bool doublehint; - if (0) printf( "fx_play_bam_bc (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); + if (0) printf( "fx_play_bam_not_blended (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); //play once set to true //check tearring.itm (0xbb effect) - ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource, false); + if ((fx->Parameter2&0x30000)==0x30000) { + doublehint = true; + } else { + doublehint = false; + } + ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource, doublehint); if (!sca) return FX_NOT_APPLIED; - if (fx->Parameter2&0x100000) { + switch (fx->Parameter2&0x300000) { + case 0x300000: + sca->SetBlend(); //per pixel transparency + break; + case 0x200000: //this is an insane combo + sca->SetBlend(); //per pixel transparency + sca->SetFade((ieByte) fx->Parameter1, fx->DiceSides); //per surface transparency + break; + case 0x100000: //per surface transparency sca->SetFade((ieByte) fx->Parameter1, fx->DiceSides); - } else { + break; + default: if (fx->Parameter1) { RGBModifier rgb; @@ -193,165 +209,49 @@ } else { playonce=false; } + switch (fx->Parameter2&0x30000) { + case 0x20000://foreground + sca->twin->ZPos+=9999; + break; + case 0x30000: //both + sca->twin->ZPos+=9999; + if (sca->twin) { + sca->twin->ZPos-=9999; + } + break; + default: //background + sca->ZPos-=9999; + break; + } if (playonce) { sca->PlayOnce(); } else { sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks); } + ScriptedAnimation *twin = sca->DetachTwin(); if (fx->Parameter2&4096) { - target->AddVVCell(sca); - } else { - sca->XPos+=fx->PosX; - sca->YPos+=fx->PosY; - Owner->GetCurrentArea()->AddVVCell(sca); - } - return FX_NOT_APPLIED; -} - -int fx_play_bam_bd (Actor* Owner, Actor* target, Effect* fx) -{ - bool playonce; - - if (0) printf( "fx_play_bam_bd (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); - //play once set to true - //check tearring.itm (0xbb effect) - ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource, false); - if (!sca) - return FX_NOT_APPLIED; - if (fx->Parameter1) { - RGBModifier rgb; - - rgb.speed=-1; - rgb.phase=0; - rgb.rgb.r=fx->Parameter1; - rgb.rgb.g=fx->Parameter1 >> 8; - rgb.rgb.b=fx->Parameter1 >> 16; - rgb.rgb.a=fx->Parameter1 >> 24; - rgb.type=RGBModifier::TINT; - sca->AlterPalette(rgb); - } - if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { - playonce=true; - } else { - playonce=false; - } - if (fx->Parameter2&1) { - //four cycles, duration is in millisecond - sca->SetDefaultDuration(sca->GetSequenceDuration(4000)); - } else { - if (playonce) { - sca->PlayOnce(); - } else { - sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks); + if (twin) { + target->AddVVCell(twin); } - } - sca->SetBlend(); - if (fx->Parameter2&2) { - sca->XPos+=fx->PosX; - sca->YPos+=fx->PosY; - Owner->GetCurrentArea()->AddVVCell(sca); - } else { target->AddVVCell(sca); - } - return FX_NOT_APPLIED; -} - -int fx_play_bam_be (Actor* Owner, Actor* target, Effect* fx) -{ - bool playonce; - - if (0) printf( "fx_play_bam_be (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); - //play once set to true - //check tearring.itm (0xbb effect) - ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource, false); - if (!sca) - return FX_NOT_APPLIED; - if (fx->Parameter1) { - RGBModifier rgb; - - rgb.speed=-1; - rgb.phase=0; - rgb.rgb.r=fx->Parameter1; - rgb.rgb.g=fx->Parameter1 >> 8; - rgb.rgb.b=fx->Parameter1 >> 16; - rgb.rgb.a=fx->Parameter1 >> 24; - rgb.type=RGBModifier::TINT; - sca->AlterPalette(rgb); - } - if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { - playonce=true; } else { - playonce=false; - } - if (fx->Parameter2&1) { - //four cycles, duration is in millisecond - sca->SetDefaultDuration(sca->GetSequenceDuration(4000)); - } else { - if (playonce) { - sca->PlayOnce(); - } else { - sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks); + //the random placement works only when it is not sticky + int x = 0; + int y = 0; + if (fx->Parameter2&1) { + ieWord tmp =(ieWord) rand(); + x = tmp&31; + y = (tmp>>5)&31; } - } - sca->SetBlend(); - if (fx->Parameter2&2) { - sca->XPos+=fx->PosX; - sca->YPos+=fx->PosY; - Owner->GetCurrentArea()->AddVVCell(sca); - } else { - target->AddVVCell(sca); - } - return FX_NOT_APPLIED; -} - -int fx_play_bam_bf (Actor* Owner, Actor* target, Effect* fx) -{ - bool playonce; - - if (0) printf( "fx_play_bam_bf (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); - //play once set to true - //check tearring.itm (0xbb effect) - ScriptedAnimation *sca = core->GetScriptedAnimation(fx->Resource, true); - if (!sca) - return FX_NOT_APPLIED; - if (fx->Parameter1) { - RGBModifier rgb; - rgb.speed=-1; - rgb.phase=0; - rgb.rgb.r=fx->Parameter1; - rgb.rgb.g=fx->Parameter1 >> 8; - rgb.rgb.b=fx->Parameter1 >> 16; - rgb.rgb.a=fx->Parameter1 >> 24; - rgb.type=RGBModifier::TINT; - sca->AlterPalette(rgb); - } - if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { - playonce=true; - } else { - playonce=false; - } - if (fx->Parameter2&1) { - //four cycles, duration is in millisecond - sca->SetDefaultDuration(sca->GetSequenceDuration(4000)); - } else { - if (playonce) { - sca->PlayOnce(); - } else { - sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks); - } - } - sca->SetBlend(); - if (fx->Parameter2&2) { - sca->XPos+=fx->PosX; - sca->YPos+=fx->PosY; - Owner->GetCurrentArea()->AddVVCell(sca); - } else { - ScriptedAnimation *twin = sca->DetachTwin(); + sca->XPos+=fx->PosX-x; + sca->YPos+=fx->PosY+sca->ZPos-y; if (twin) { - target->AddVVCell(twin); + twin->XPos+=fx->PosX-x; + twin->YPos+=fx->PosY+twin->ZPos-y; + Owner->GetCurrentArea()->AddVVCell(twin); } - target->AddVVCell(sca); + Owner->GetCurrentArea()->AddVVCell(sca); } return FX_NOT_APPLIED; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-04-10 19:35:55
|
Revision: 4586 http://gemrb.svn.sourceforge.net/gemrb/?rev=4586&view=rev Author: avenger_teambg Date: 2007-04-10 12:35:54 -0700 (Tue, 10 Apr 2007) Log Message: ----------- jumble curse (gethit+hiccup string) fixed IE_ANI_DAMAGE stance Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Actor.cpp gemrb/trunk/gemrb/plugins/Core/Actor.h gemrb/trunk/gemrb/plugins/Core/CharAnimations.cpp gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp gemrb/trunk/gemrb/plugins/Core/Projectile.cpp gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp Modified: gemrb/trunk/gemrb/plugins/Core/Actor.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-04-10 19:35:00 UTC (rev 4585) +++ gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-04-10 19:35:54 UTC (rev 4586) @@ -144,7 +144,7 @@ #define OV_MINORGLOBE 2 #define OV_SHIELDGLOBE 3 #define OV_GREASE 4 -#define OV_WEB 5 +#define OV_WEB 5 #define OV_BOUNCE 6 //bouncing #define OV_BOUNCE2 7 //bouncing activated static ieResRef overlay[OVERLAY_COUNT]={"SPENTACI","SANCTRY","MINORGLB","SPSHIELD", @@ -155,7 +155,7 @@ static bool CHECK_ABILITIES=false; //internal flags for calculating to hit -#define WEAPON_FIST 0 +#define WEAPON_FIST 0 #define WEAPON_MELEE 1 #define WEAPON_RANGED 2 #define WEAPON_STYLEMASK 15 @@ -1309,6 +1309,12 @@ } } +void Actor::GetHit() +{ + SetStance( IE_ANI_DAMAGE ); + DisplayStringCore(this, VB_DAMAGE, DS_CONSOLE|DS_CONST ); +} + //returns actual damage int Actor::Damage(int damage, int damagetype, Actor *hitter) { @@ -1336,6 +1342,7 @@ damagelevel = 3; } } + GetHit(); if (damagetype & (DAMAGE_FIRE|DAMAGE_MAGICFIRE) ) { PlayDamageAnimation(DL_FIRE+damagelevel); } else if (damagetype & (DAMAGE_COLD|DAMAGE_MAGICCOLD) ) { @@ -1351,7 +1358,6 @@ } printMessage("Actor"," ",GREEN); printf("%d damage taken.\n", LastDamage); - DisplayStringCore(this, VB_DAMAGE, DS_CONSOLE|DS_CONST ); if (InParty) { if (chp<(signed) Modified[IE_MAXHITPOINTS]/10) { core->Autopause(AP_WOUNDED); @@ -2592,7 +2598,7 @@ // Drawn with transparency. // distance between copies depends on IE_MOVEMENTRATE // TODO: actually, the direction is the real movement direction, - // not the (rounded) direction given Face + // not the (rounded) direction given Face // Uses extraCovers 0-2 // * actor itself // Uses main spritecover @@ -2738,7 +2744,15 @@ int StanceID = GetStance(); if (ca->autoSwitchOnEnd) { - SetStance( ca->nextStanceID ); + int nextstance = ca->nextStanceID; +/* + if (nextstance == IE_ANI_READY) { + if (!core->GetGame()->CombatCounter) { + nextstance = IE_ANI_AWAKE; + } + } +*/ + SetStance( nextstance ); ca->autoSwitchOnEnd = false; return true; } @@ -3085,43 +3099,43 @@ bool Actor::CastSpellPoint( ieResRef SpellResRef, Point &target ) { - if (! spellbook.HaveSpell( SpellResRef, HS_DEPLETE )) { - return false; - } + if (! spellbook.HaveSpell( SpellResRef, HS_DEPLETE )) { + return false; + } - Spell* spl = core->GetSpell( SpellResRef ); - //cfb - EffectQueue *fxqueue=spl->GetEffectBlock(-1); - fxqueue->SetOwner(this); - fxqueue->ApplyAllEffects(this); - //spell - Projectile *pro=spl->GetProjectile(GetXPLevel(true)); - pro->SetCaster(globalID); - GetCurrentArea()->AddProjectile(pro, Pos, target); - return true; + Spell* spl = core->GetSpell( SpellResRef ); + //cfb + EffectQueue *fxqueue=spl->GetEffectBlock(-1); + fxqueue->SetOwner(this); + fxqueue->ApplyAllEffects(this); + //spell + Projectile *pro=spl->GetProjectile(GetXPLevel(true)); + pro->SetCaster(globalID); + GetCurrentArea()->AddProjectile(pro, Pos, target); + return true; } bool Actor::CastSpell( ieResRef SpellResRef, Scriptable* target ) { - if (! spellbook.HaveSpell( SpellResRef, HS_DEPLETE )) { - return false; - } + if (! spellbook.HaveSpell( SpellResRef, HS_DEPLETE )) { + return false; + } if (target->Type!=ST_ACTOR) { return CastSpellPoint(SpellResRef, target->Pos); } Actor *Target = (Actor *) target; - Spell* spl = core->GetSpell( SpellResRef ); - //cfb - EffectQueue *fxqueue=spl->GetEffectBlock(-1); - fxqueue->SetOwner(this); - fxqueue->ApplyAllEffects(this); - //spell - Projectile *pro=spl->GetProjectile(GetXPLevel(true)); - pro->SetCaster(globalID); - GetCurrentArea()->AddProjectile(pro, Pos, Target->globalID); - return true; + Spell* spl = core->GetSpell( SpellResRef ); + //cfb + EffectQueue *fxqueue=spl->GetEffectBlock(-1); + fxqueue->SetOwner(this); + fxqueue->ApplyAllEffects(this); + //spell + Projectile *pro=spl->GetProjectile(GetXPLevel(true)); + pro->SetCaster(globalID); + GetCurrentArea()->AddProjectile(pro, Pos, Target->globalID); + return true; } bool Actor::IsReverseToHit() Modified: gemrb/trunk/gemrb/plugins/Core/Actor.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-04-10 19:35:00 UTC (rev 4585) +++ gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-04-10 19:35:54 UTC (rev 4586) @@ -317,6 +317,8 @@ void ReactToDeath(const char *deadname); /* called when someone talks to Actor */ void DialogInterrupt(); + /* called when actor was hit */ + void GetHit(); /* deals damage to this actor */ int Damage(int damage, int damagetype, Actor *hitter); /* drops items from inventory to current spot */ Modified: gemrb/trunk/gemrb/plugins/Core/CharAnimations.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/CharAnimations.cpp 2007-04-10 19:35:00 UTC (rev 4585) +++ gemrb/trunk/gemrb/plugins/Core/CharAnimations.cpp 2007-04-10 19:35:54 UTC (rev 4586) @@ -253,7 +253,7 @@ } for (unsigned int i = 0; i < Colors[6]; i++) { core->GetPalette( Colors[i]&255, size, - &palette[PAL_MAIN]->col[dest] ); + &palette[PAL_MAIN]->col[dest] ); //Color* NewPal = core->GetPalette( Colors[i]&255, size ); //memcpy( &palette->col[dest], NewPal, size*sizeof( Color ) ); dest +=size; @@ -545,17 +545,17 @@ All armourlevels are drawn simultaneously. There is no orientation or stance. - WEST PART | EAST PART - | - NW NNW N NNE NE + WEST PART | EAST PART + | + NW NNW N NNE NE NW 006 007 008 009 010 NE WNW 005 | 011 ENE - W 004 xxx 012 E + W 004 xxx 012 E WSW 003 | 013 ESE SW 002 001 000 015 014 SE - SW SSW S SSE SE - | - | + SW SSW S SSE SE + | + | */ @@ -603,6 +603,10 @@ //setting up the sequencing of animation cycles autoSwitchOnEnd = false; switch (StanceID) { + case IE_ANI_DAMAGE: + nextStanceID = IE_ANI_READY; + autoSwitchOnEnd = true; + break; case IE_ANI_SLEEP: //going to sleep nextStanceID = IE_ANI_TWITCH; autoSwitchOnEnd = true; @@ -686,10 +690,10 @@ // off-hand if (WeaponType == IE_ANI_WEAPON_1H) { GetEquipmentResRef(OffhandRef,false,NewResRef,Cycle, - equipdat); + equipdat); } else { // IE_ANI_WEAPON_2W GetEquipmentResRef(OffhandRef,true,NewResRef,Cycle, - equipdat); + equipdat); } } else if (part == actorPartCount+2) { if (HelmetRef[0] == 0) continue; @@ -778,6 +782,7 @@ //setting up the sequencing of animation cycles switch (StanceID) { + case IE_ANI_DAMAGE: case IE_ANI_SLEEP: case IE_ANI_TWITCH: case IE_ANI_DIE: Modified: gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp 2007-04-10 19:35:00 UTC (rev 4585) +++ gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp 2007-04-10 19:35:54 UTC (rev 4586) @@ -303,7 +303,8 @@ } int tmp=(int) actor->StrRefs[Strref]; - if (tmp == -1) { + // 0 is also illegal as string constant (in pst at least) + if (tmp <= 0) { actor->ResolveStringConstant( sb.Sound, (unsigned int) Strref); } Strref = tmp; Modified: gemrb/trunk/gemrb/plugins/Core/Projectile.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Projectile.cpp 2007-04-10 19:35:00 UTC (rev 4585) +++ gemrb/trunk/gemrb/plugins/Core/Projectile.cpp 2007-04-10 19:35:54 UTC (rev 4586) @@ -161,6 +161,8 @@ Actor *original = area->GetActorByGlobalID(Caster); effects->SetOwner(original?original:target); effects->AddAllEffects(target); + //not simply nulling it, addalleffects copies them + delete effects; effects = NULL; return; } Modified: gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-04-10 19:35:00 UTC (rev 4585) +++ gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-04-10 19:35:54 UTC (rev 4586) @@ -1836,8 +1836,7 @@ AnimationFactory* af = ( AnimationFactory* ) core->GetResourceMgr()->GetFactoryResource( ResRef, - IE_BAM_CLASS_ID, - IE_NORMAL ); + IE_BAM_CLASS_ID, IE_NORMAL ); if (!af) { return RuntimeError( "BAM not found" ); } @@ -2216,8 +2215,7 @@ map->LinkedLabel = lc; AnimationFactory* af = ( AnimationFactory* ) core->GetResourceMgr()->GetFactoryResource( Flag, - IE_BAM_CLASS_ID, - IE_NORMAL ); + IE_BAM_CLASS_ID, IE_NORMAL ); if (af) { for (int i=0;i<8;i++) { map->Flag[i] = af->GetFrame(i,0); @@ -2739,8 +2737,7 @@ if (str == NULL ) { AnimationFactory* af = ( AnimationFactory* ) core->GetResourceMgr()->GetFactoryResource( ResRef, - IE_BAM_CLASS_ID, - IE_NORMAL ); + IE_BAM_CLASS_ID, IE_NORMAL ); if (!af) { printMessage("GUISCript","PLT/BAM not found for ref: ",YELLOW); printf("%s\n", ResRef); @@ -2817,8 +2814,7 @@ AnimationFactory* af = ( AnimationFactory* ) core->GetResourceMgr()->GetFactoryResource( ResRef, - IE_BAM_CLASS_ID, - IE_NORMAL ); + IE_BAM_CLASS_ID, IE_NORMAL ); if (!af) return NULL; Sprite2D* Picture = af->GetFrame ( FrameIndex, CycleIndex ); @@ -4437,8 +4433,7 @@ } AnimationFactory* af = ( AnimationFactory* ) core->GetResourceMgr()->GetFactoryResource( IconResRef, - IE_BAM_CLASS_ID, - IE_NORMAL ); + IE_BAM_CLASS_ID, IE_NORMAL ); if (!af) { return RuntimeError( "BAM not found" ); } @@ -6781,8 +6776,7 @@ //FIXME: this is a hardcoded resource (pst has no such one) AnimationFactory* bam = ( AnimationFactory* ) core->GetResourceMgr()->GetFactoryResource( GUIResRef[Index], - IE_BAM_CLASS_ID, - IE_NORMAL ); + IE_BAM_CLASS_ID, IE_NORMAL ); if (!bam) { return RuntimeError( "BAM not found" ); } @@ -6877,8 +6871,7 @@ //FIXME: this is a hardcoded resource (pst has no such one) AnimationFactory* bam = ( AnimationFactory* ) core->GetResourceMgr()->GetFactoryResource( "guibtbut", - IE_BAM_CLASS_ID, - IE_NORMAL ); + IE_BAM_CLASS_ID, IE_NORMAL ); if (!bam) { return RuntimeError( "BAM not found" ); } @@ -6979,8 +6972,7 @@ //FIXME: this is a hardcoded resource (pst has no such one) AnimationFactory* bam = ( AnimationFactory* ) core->GetResourceMgr()->GetFactoryResource( "guibtbut", - IE_BAM_CLASS_ID, - IE_NORMAL ); + IE_BAM_CLASS_ID, IE_NORMAL ); if (!bam) { return RuntimeError( "BAM not found" ); } Modified: gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-10 19:35:00 UTC (rev 4585) +++ gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-10 19:35:54 UTC (rev 4586) @@ -425,11 +425,21 @@ //0xd3 fx_jumble_curse int fx_jumble_curse (Actor* /*Owner*/, Actor* target, Effect* fx) { - if (0) printf( "fx_jumble_curse (%2d): Par1: %d Par2: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); + if (0) printf( "fx_jumble_curse (%2d)\n", fx->Opcode ); + if (!(core->GetGame()->GameTime%100)) { + //hiccups + //PST has this hardcoded deep in the engine + //gemrb lets you specify the strref in P#1 + ieStrRef tmp = fx->Parameter1; + if (!tmp) tmp = 46633; + char *tmpstr = core->GetString(tmp, IE_STR_SPEECH|IE_STR_SOUND); + target->DisplayHeadText(tmpstr); + //tmpstr shouldn't be freed, it is taken care by Actor + target->GetHit(); + } STAT_SET( IE_DEADMAGIC, 1); STAT_SET( IE_SPELLFAILUREMAGE, 100); STAT_SET( IE_SPELLFAILUREPRIEST, 100); STAT_SET( IE_SPELLFAILUREINNATE, 100); - //hiccups return FX_APPLIED; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wjp...@us...> - 2007-04-12 20:08:49
|
Revision: 4590 http://gemrb.svn.sourceforge.net/gemrb/?rev=4590&view=rev Author: wjpalenstijn Date: 2007-04-12 13:08:50 -0700 (Thu, 12 Apr 2007) Log Message: ----------- change SetColorMod semantics slightly to fix PS:T global pulse effect Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Actor.cpp gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp Modified: gemrb/trunk/gemrb/plugins/Core/Actor.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-04-11 19:08:02 UTC (rev 4589) +++ gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-04-12 20:08:50 UTC (rev 4590) @@ -2318,15 +2318,14 @@ ca->GlobalColorMod.rgb.b = b; if (phase >= 0) ca->GlobalColorMod.phase = phase; - else - ca->GlobalColorMod.phase = 0; } else { ca->ColorMods[location].type = type; ca->ColorMods[location].speed = speed; ca->ColorMods[location].rgb.r = r; ca->ColorMods[location].rgb.g = g; ca->ColorMods[location].rgb.b = b; - // keep phase as-is, to prevent the phase being reset each AI cycle + if (phase >= 0) + ca->ColorMods[location].phase = phase; } } Modified: gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-04-11 19:08:02 UTC (rev 4589) +++ gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-04-12 20:08:50 UTC (rev 4590) @@ -1680,7 +1680,7 @@ int speed = (fx->Parameter2 >> 16) & 0xFF; target->SetColorMod(-1, RGBModifier::ADD, speed, fx->Parameter1 >> 8, fx->Parameter1 >> 16, - fx->Parameter1 >> 24); + fx->Parameter1 >> 24, 0); return FX_NOT_APPLIED; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-04-13 20:09:12
|
Revision: 4591 http://gemrb.svn.sourceforge.net/gemrb/?rev=4591&view=rev Author: avenger_teambg Date: 2007-04-13 13:09:06 -0700 (Fri, 13 Apr 2007) Log Message: ----------- implemented detect evil opcode (pst) - coloured highlight of actors in line of sight. Customisable with distance/color/speed/ids targeting Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp gemrb/trunk/gemrb/plugins/Core/EffectQueue.h gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp Modified: gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp 2007-04-12 20:08:50 UTC (rev 4590) +++ gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp 2007-04-13 20:09:06 UTC (rev 4591) @@ -26,8 +26,8 @@ #include "EffectQueue.h" #include "SymbolMgr.h" #include "Game.h" +#include "Map.h" - static int initialized = 0; static EffectRef *effectnames = NULL; static EffectRef effect_refs[MAX_EFFECTS]; @@ -49,6 +49,51 @@ #define MAX_TIMING_MODE 11 */ +bool EffectQueue::match_ids(Actor *target, int table, ieDword value) +{ + if (value == 0) { + return true; + } + + int a, stat; + + switch (table) { + case 2: //EA + stat = IE_EA; break; + case 3: //GENERAL + stat = IE_GENERAL; break; + case 4: //RACE + stat = IE_RACE; break; + case 5: //CLASS + stat = IE_CLASS; break; + case 6: //SPECIFIC + stat = IE_SPECIFIC; break; + case 7: //GENDER + stat = IE_SEX; break; + case 8: //ALIGNMENT + stat = target->GetStat(IE_ALIGNMENT); + a = value&15; + if (a) { + if (a != ( stat & 15 )) { + return false; + } + } + a = value & 0xf0; + if (a) { + if (a != ( stat & 0xf0 )) { + return false; + } + } + return true; + default: + return false; + } + if (target->GetStat(stat)==value) { + return true; + } + return false; +} + static bool fx_instant[MAX_TIMING_MODE]={true,true,true,false,false,false,false,false,true,true,true}; inline bool IsInstant(ieByte timingmode) @@ -1176,3 +1221,25 @@ return 0; } +void EffectQueue::AffectAllInRange(Map *map, Point &pos, int idstype, int idsvalue, + unsigned int range) +{ + int cnt = map->GetActorCount(true); + while(cnt--) { + Actor *actor = map->GetActor(cnt,true); + //distance + if (Distance(pos, actor)>range) { + continue; + } + //ids targeting + if (!match_ids(actor, idstype, idsvalue)) { + continue; + } + //line of sight + if (!map->IsVisible(actor->Pos, pos)) { + continue; + } + AddAllEffects(actor); + } +} + Modified: gemrb/trunk/gemrb/plugins/Core/EffectQueue.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/EffectQueue.h 2007-04-12 20:08:50 UTC (rev 4590) +++ gemrb/trunk/gemrb/plugins/Core/EffectQueue.h 2007-04-13 20:09:06 UTC (rev 4591) @@ -34,8 +34,8 @@ #include "Effect.h" class Actor; +class Map; - /** Maximum number of different Effect opcodes */ #define MAX_EFFECTS 512 @@ -127,8 +127,6 @@ /** release effect list when Interface is destroyed */ void EffectQueue_ReleaseMemory(); -bool match_ids(Actor *target, int table, ieDword value); - /** Check if opcode is for an effect that takes a color slot as parameter. */ bool IsColorslotEffect(int opcode); @@ -204,10 +202,14 @@ // returns -1 if bounced, 0 if resisted, 1 if accepted spell int CheckImmunity(Actor *target); + // apply this effectqueue on all actors matching ids targeting + // from pos, in range (no cone size yet) + void AffectAllInRange(Map *map, Point &pos, int idstype, int idsvalue, unsigned int range); /** Lists contents of the queue on a terminal for debugging */ void dump(); //resolve effect static int ResolveEffect(EffectRef &effect_reference); + static bool match_ids(Actor *target, int table, ieDword value); private: //use the effect reference style calls from outside static Effect *CreateEffect(ieDword opcode, ieDword param1, ieDword param2, ieDword timing); Modified: gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-04-12 20:08:50 UTC (rev 4590) +++ gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-04-13 20:09:06 UTC (rev 4591) @@ -730,60 +730,6 @@ core->FreeResRefTable(spell_hits, shcount); } -// Helper macros and functions for effect opcodes -/* -#define CHECK_LEVEL() { \ - int level = target->GetXPLevel( true ); \ - if ((fx->DiceSides != 0 || fx->DiceThrown != 0) && (level < (int)fx->DiceSides || level > (int)fx->DiceThrown)) \ - return FX_NOT_APPLIED; \ - } -*/ - -bool match_ids(Actor *target, int table, ieDword value) -{ - if (value == 0) { - return true; - } - - int a, stat; - - switch (table) { - case 2: //EA - stat = IE_EA; break; - case 3: //GENERAL - stat = IE_GENERAL; break; - case 4: //RACE - stat = IE_RACE; break; - case 5: //CLASS - stat = IE_CLASS; break; - case 6: //SPECIFIC - stat = IE_SPECIFIC; break; - case 7: //GENDER - stat = IE_SEX; break; - case 8: //ALIGNMENT - stat = target->GetStat(IE_ALIGNMENT); - a = value&15; - if (a) { - if (a != ( stat & 15 )) { - return false; - } - } - a = value & 240; - if (a) { - if (a != ( stat & 240 )) { - return false; - } - } - return true; - default: - return false; - } - if (target->GetStat(stat)==value) { - return true; - } - return false; -} - static inline void HandleBonus(Actor *target, int stat, int mod, int mode) { if (mode==FX_DURATION_INSTANT_PERMANENT) { @@ -1743,7 +1689,7 @@ int fx_kill_creature_type (Actor* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_kill_creature_type (%2d): Value: %d, IDS: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - if (match_ids( target, fx->Parameter1, fx->Parameter2) ) { + if (EffectQueue::match_ids( target, fx->Parameter1, fx->Parameter2) ) { //convert it to a death opcode or apply the new effect? fx->Opcode = EffectQueue::ResolveEffect(fx_death_ref); fx->TimingMode = FX_DURATION_INSTANT_PERMANENT; @@ -2983,7 +2929,7 @@ { if (0) printf( "fx_find_traps (%2d)\n", fx->Opcode ); //reveal trapped containers, doors, triggers that are in the visible range - ieDword range = target->GetStat(IE_VISUALRANGE); + ieDword range = target->GetStat(IE_VISUALRANGE)*10; TileMap *TMap = target->GetCurrentArea()->TMap; @@ -3270,7 +3216,7 @@ if ( STATE_GET(STATE_DEAD) ) { return FX_NOT_APPLIED; } - if (match_ids( target, fx->Parameter1, fx->Parameter2) ) { + if (EffectQueue::match_ids( target, fx->Parameter1, fx->Parameter2) ) { STAT_SET( IE_HELD, 1); return FX_APPLIED; } @@ -3287,7 +3233,7 @@ return FX_NOT_APPLIED; } - if (match_ids( target, fx->Parameter1, fx->Parameter2) ) { + if (EffectQueue::match_ids( target, fx->Parameter1, fx->Parameter2) ) { STAT_SET( IE_HELD, 1); target->AddPortraitIcon(PI_HELD); return FX_APPLIED; @@ -3301,7 +3247,7 @@ int fx_apply_effect (Actor* Owner, Actor* target, Effect* fx) { if (0) printf( "fx_apply_effect (%2d) %s", fx->Opcode, fx->Resource ); - if (match_ids( target, fx->Parameter1, fx->Parameter2) ) { + if (EffectQueue::match_ids( target, fx->Parameter1, fx->Parameter2) ) { //apply effect core->ApplyEffect(fx->Resource, target, Owner, fx->Power); } @@ -3778,7 +3724,7 @@ condition = target->LastDamage; break; case COND_NEAR: // - condition = Distance(actor, target)<30; + condition = PersonalDistance(actor, target)<30; break; case COND_HP_HALF: condition = actor->GetStat(IE_HITPOINTS)<actor->GetStat(IE_MAXHITPOINTS)/2; @@ -3892,7 +3838,7 @@ int fx_disintegrate (Actor* Owner, Actor* target, Effect* fx) { if (0) printf( "fx_disintegrate (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - if (match_ids( target, fx->Parameter1, fx->Parameter2) ) { + if (EffectQueue::match_ids( target, fx->Parameter1, fx->Parameter2) ) { target->Damage(0, fx->Parameter2, Owner); //hmm? //death has damage type too target->Die(Owner); @@ -4322,7 +4268,7 @@ int fx_apply_effect_curse (Actor* Owner, Actor* target, Effect* fx) { if (0) printf( "fx_apply_effect_curse (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - if (match_ids( target, fx->Parameter1, fx->Parameter2) ) { + if (EffectQueue::match_ids( target, fx->Parameter1, fx->Parameter2) ) { //load effect and add it to the end of the effect queue? core->ApplyEffect(fx->Resource, target, Owner, fx->Power); } Modified: gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-12 20:08:50 UTC (rev 4590) +++ gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-13 20:09:06 UTC (rev 4591) @@ -415,11 +415,31 @@ } //0xd2 fx_detect_evil -int fx_detect_evil (Actor* /*Owner*/, Actor* /*target*/, Effect* fx) +EffectRef single_color_pulse_ref={"Color:BriefRGB",NULL,-1}; + +int fx_detect_evil (Actor* Owner, Actor* target, Effect* fx) { if (0) printf( "fx_detect_evil (%2d): Par1: %d Par2: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); + ieDword type = fx->Parameter2; + //default is alignment/evil/speed 30/range 10 + if (!type) type = 0x08031e0a; + int speed = (type&0xff00)>>8; + if (!speed) speed=30; + if (!(core->GetGame()->GameTime%speed)) { + ieDword color = fx->Parameter1; + //default is magenta (rgba) + if (!color) color = 0xff00ff00; + Effect *newfx = EffectQueue::CreateEffect(single_color_pulse_ref, color, speed<<16, FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES); + newfx->Target=FX_TARGET_PRESET; + EffectQueue *fxqueue = new EffectQueue(); + fxqueue->SetOwner(Owner); + fxqueue->AddEffect(newfx); + delete newfx; - return FX_NOT_APPLIED; + fxqueue->AffectAllInRange(target->GetCurrentArea(), target->Pos, (type&0xff000000)>>24, (type&0xff0000)>>16, (type&0xff)*10); + delete fxqueue; + } + return FX_APPLIED; } //0xd3 fx_jumble_curse This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-04-14 11:49:04
|
Revision: 4592 http://gemrb.svn.sourceforge.net/gemrb/?rev=4592&view=rev Author: avenger_teambg Date: 2007-04-14 04:49:04 -0700 (Sat, 14 Apr 2007) Log Message: ----------- implemented scrolling w. speed in MoveView* actions and opcodes moved centering to GlobalTimer from SDLVideo Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Actions.cpp gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp gemrb/trunk/gemrb/plugins/Core/GameControl.cpp gemrb/trunk/gemrb/plugins/Core/GlobalTimer.cpp gemrb/trunk/gemrb/plugins/Core/GlobalTimer.h gemrb/trunk/gemrb/plugins/Core/Interface.cpp gemrb/trunk/gemrb/plugins/Core/Interface.h gemrb/trunk/gemrb/plugins/Core/MapControl.cpp gemrb/trunk/gemrb/plugins/Core/TileOverlay.cpp gemrb/trunk/gemrb/plugins/Core/Video.h gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.cpp gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.h Modified: gemrb/trunk/gemrb/plugins/Core/Actions.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-04-13 20:09:06 UTC (rev 4591) +++ gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-04-14 11:49:04 UTC (rev 4592) @@ -895,7 +895,7 @@ void GameScript::MoveViewPoint(Scriptable* /*Sender*/, Action* parameters) { - core->MoveViewportTo( parameters->pointParameter.x, parameters->pointParameter.y, true ); + core->timer->SetMoveViewPort( parameters->pointParameter.x, parameters->pointParameter.y, parameters->int0Parameter, true ); } void GameScript::MoveViewObject(Scriptable* Sender, Action* parameters) @@ -904,7 +904,7 @@ if (!scr) { return; } - core->MoveViewportTo( scr->Pos.x, scr->Pos.y, true ); + core->timer->SetMoveViewPort( scr->Pos.x, scr->Pos.y, parameters->int0Parameter, true ); } void GameScript::AddWayPoint(Scriptable* Sender, Action* parameters) Modified: gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp 2007-04-13 20:09:06 UTC (rev 4591) +++ gemrb/trunk/gemrb/plugins/Core/GSUtils.cpp 2007-04-14 11:49:04 UTC (rev 4592) @@ -233,9 +233,9 @@ return ret; } -void ClickCore(Point &point, int type, int /*speed*/) +void ClickCore(Point &point, int type, int speed) { - core->MoveViewportTo( point.x, point.y, true ); + core->timer->SetMoveViewPort( point.x, point.y, speed, true ); Video *video = core->GetVideoDriver(); video->ConvertToScreen(point.x, point.y); video->MoveMouse(point.x, point.y); Modified: gemrb/trunk/gemrb/plugins/Core/GameControl.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameControl.cpp 2007-04-13 20:09:06 UTC (rev 4591) +++ gemrb/trunk/gemrb/plugins/Core/GameControl.cpp 2007-04-14 11:49:04 UTC (rev 4592) @@ -260,17 +260,19 @@ ChangeMap(core->GetFirstSelectedPC(), false); } Video* video = core->GetVideoDriver(); - Region viewport = core->GetVideoDriver()->GetViewport(); - viewport.x += video->moveX; - viewport.y += video->moveY; - core->MoveViewportTo( viewport.x, viewport.y, false ); + if (video->moveX || video->moveY) { + Region viewport = video->GetViewport(); + viewport.x += video->moveX; + viewport.y += video->moveY; + core->timer->SetMoveViewPort( viewport.x, viewport.y, 0, false ); + } Region screen( x + XPos, y + YPos, Width, Height ); Map* area = game->GetCurrentArea( ); if (!area) { - core->GetVideoDriver()->DrawRect( screen, blue, true ); + video->DrawRect( screen, blue, true ); return; } - core->GetVideoDriver()->DrawRect( screen, black, true ); + video->DrawRect( screen, black, true ); //drawmap should be here so it updates fog of war area->DrawMap( screen, this ); @@ -352,7 +354,7 @@ c.b = 0x7F; } - core->GetVideoDriver()->DrawPolyline( poly, c, true ); + video->DrawPolyline( poly, c, true ); } } @@ -1327,22 +1329,24 @@ break; case GEM_ALT: DebugFlags |= DEBUG_SHOW_CONTAINERS; - break; + return; case GEM_TAB: DebugFlags |= DEBUG_XXX; printf( "TAB pressed\n" ); - break; + return; case GEM_MOUSEOUT: moveX = 0; moveY = 0; - break; + return; + default: + return; } if (ScreenFlags & SF_LOCKSCROLL) { moveX = 0; moveY = 0; } else { - core->MoveViewportTo( Viewport.x, Viewport.y, false ); + core->timer->SetMoveViewPort( Viewport.x, Viewport.y, 0, false ); } } @@ -1678,7 +1682,7 @@ //allow mouse selection from dialog (even though screen is locked) core->GetVideoDriver()->SetMouseEnabled(true); - core->MoveViewportTo( tgt->Pos.x, tgt->Pos.y, true ); + core->timer->SetMoveViewPort( tgt->Pos.x, tgt->Pos.y, 0, true ); //there are 3 bits, if they are all unset, the dialog freezes scripts if (!(dlg->Flags&7) ) { DialogueFlags |= DF_FREEZE_SCRIPTS; @@ -1967,7 +1971,7 @@ //center on first selected actor Region vp = core->GetVideoDriver()->GetViewport(); if (ScreenFlags&SF_CENTERONACTOR) { - core->MoveViewportTo( pc->Pos.x, pc->Pos.y, true ); + core->timer->SetMoveViewPort( pc->Pos.x, pc->Pos.y, 0, true ); ScreenFlags&=~SF_CENTERONACTOR; } } Modified: gemrb/trunk/gemrb/plugins/Core/GlobalTimer.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GlobalTimer.cpp 2007-04-13 20:09:06 UTC (rev 4591) +++ gemrb/trunk/gemrb/plugins/Core/GlobalTimer.cpp 2007-04-14 11:49:04 UTC (rev 4592) @@ -52,6 +52,7 @@ waitCounter = 0; shakeCounter = 0; startTime = 0; //forcing an update + speed = 0; ClearAnimations(); } @@ -70,6 +71,18 @@ game->RealTime+=advance; } +void GlobalTimer::SetMoveViewPort(ieDword x, ieDword y, int spd, bool center) +{ + speed=spd; + currentVP=core->GetVideoDriver()->GetViewport(); + if (center) { + x-=currentVP.w/2; + y-=currentVP.h/2; + } + goal.x=(short) x; + goal.y=(short) y; +} + void GlobalTimer::Update() { Map *map; @@ -77,6 +90,7 @@ GameControl* gc; unsigned long thisTime; unsigned long advance; + Video *video = core->GetVideoDriver(); UpdateAnimations(); @@ -86,9 +100,33 @@ return; } ieDword count = advance/interval; + + int x = currentVP.x; + int y = currentVP.y; + if ( (x != goal.x) || (y != goal.y)) { + if (speed) { + if (x<goal.x) { + x+=speed; + if (x>goal.x) x=goal.x; + } else { + x-=speed; + if (x<goal.x) x=goal.x; + } + if (y<goal.y) { + y+=speed; + if (y>goal.y) y=goal.y; + } else { + y-=speed; + if (y<goal.y) y=goal.y; + } + } else { + x=goal.x; + y=goal.y; + } + currentVP.x=x; + currentVP.y=y; + } if (shakeCounter) { - int x = shakeStartVP.x; - int y = shakeStartVP.y; shakeCounter-=count; if (shakeCounter<0) { shakeCounter=0; @@ -97,34 +135,34 @@ x += (rand()%shakeX) - (shakeX>>1); y += (rand()%shakeY) - (shakeY>>1); } - core->GetVideoDriver()->MoveViewportTo(x,y,false); } + video->MoveViewportTo(x,y); if (fadeToCounter) { fadeToCounter-=count; if (fadeToCounter<0) { fadeToCounter=0; } - core->GetVideoDriver()->SetFadePercent( ( ( fadeToMax - fadeToCounter ) * 100 ) / fadeToMax ); + video->SetFadePercent( ( ( fadeToMax - fadeToCounter ) * 100 ) / fadeToMax ); goto end; //hmm, freeze gametime? } if (fadeFromCounter!=fadeFromMax) { if (fadeFromCounter>fadeFromMax) { fadeFromCounter-=advance/interval; if (fadeFromCounter<fadeFromMax) { - fadeFromCounter=fadeFromMax; + fadeFromCounter=fadeFromMax; } //don't freeze gametime when already dark } else { fadeFromCounter+=advance/interval; if (fadeToCounter>fadeFromMax) { - fadeToCounter=fadeFromMax; + fadeToCounter=fadeFromMax; } - core->GetVideoDriver()->SetFadePercent( ( ( fadeFromMax - fadeFromCounter ) * 100 ) / fadeFromMax ); + video->SetFadePercent( ( ( fadeFromMax - fadeFromCounter ) * 100 ) / fadeFromMax ); goto end; //freeze gametime? } } if (fadeFromCounter==fadeFromMax) { - core->GetVideoDriver()->SetFadePercent( 0 ); + video->SetFadePercent( 0 ); } gc = core->GetGameControl(); if (!gc) { @@ -258,5 +296,5 @@ { this->shakeX = shakeX; this->shakeY = shakeY; - shakeCounter = Count; + shakeCounter = Count+1; } Modified: gemrb/trunk/gemrb/plugins/Core/GlobalTimer.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GlobalTimer.h 2007-04-13 20:09:06 UTC (rev 4591) +++ gemrb/trunk/gemrb/plugins/Core/GlobalTimer.h 2007-04-14 11:49:04 UTC (rev 4592) @@ -38,6 +38,10 @@ unsigned long shakeX, shakeY; unsigned int first_animation; std::vector<AnimationRef*> animations; + //move viewport to this coordinate + Point goal; + int speed; + Region currentVP; public: GlobalTimer(void); ~GlobalTimer(void); @@ -45,19 +49,16 @@ void Init(); void Freeze(); void Update(); + void SetMoveViewPort(ieDword x, ieDword y, int spd, bool center); void SetFadeToColor(unsigned long Count); void SetFadeFromColor(unsigned long Count); void SetWait(unsigned long Count); - //void SetCutScene(GameScript* script); void SetScreenShake(unsigned long shakeX, unsigned long shakeY, unsigned long Count); void AddAnimation(ControlAnimation* ctlanim, unsigned long time); void RemoveAnimation(ControlAnimation* ctlanim); void ClearAnimations(); void UpdateAnimations(); -public: - //bool CutSceneMode; - Region shakeStartVP; }; #endif Modified: gemrb/trunk/gemrb/plugins/Core/Interface.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Interface.cpp 2007-04-13 20:09:06 UTC (rev 4591) +++ gemrb/trunk/gemrb/plugins/Core/Interface.cpp 2007-04-14 11:49:04 UTC (rev 4592) @@ -4771,12 +4771,6 @@ s->items.push_back( new STOItem() ); } -void Interface::MoveViewportTo(int x, int y, bool center) -{ - video->MoveViewportTo( x, y, center ); - timer->shakeStartVP = video->GetViewport(); -} - //plays stock sound listed in defsound.2da void Interface::PlaySound(int index) { Modified: gemrb/trunk/gemrb/plugins/Core/Interface.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Interface.h 2007-04-13 20:09:06 UTC (rev 4591) +++ gemrb/trunk/gemrb/plugins/Core/Interface.h 2007-04-14 11:49:04 UTC (rev 4592) @@ -105,11 +105,11 @@ ItemList(unsigned int size, int label) { ResRefs = (ieResRef *) calloc(size, sizeof(ieResRef) ); Count = size; - if ((size&1) && (label==2)) { - WeightOdds=true; - } else { - WeightOdds=false; - } + if ((size&1) && (label==2)) { + WeightOdds=true; + } else { + WeightOdds=false; + } } ~ItemList() { if (ResRefs) { @@ -558,7 +558,6 @@ void FreeSPLExt(SPLExtHeader *p, Effect *e); WorldMapArray *NewWorldMapArray(int count); void DoTheStoreHack(Store *s); - void MoveViewportTo(int x, int y, bool center); /** plays stock gui sound referenced by index */ void PlaySound(int idx); /** returns true if resource exists */ Modified: gemrb/trunk/gemrb/plugins/Core/MapControl.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/MapControl.cpp 2007-04-13 20:09:06 UTC (rev 4591) +++ gemrb/trunk/gemrb/plugins/Core/MapControl.cpp 2007-04-14 11:49:04 UTC (rev 4592) @@ -342,7 +342,7 @@ if (xp < 0) xp = 0; if (yp < 0) yp = 0; - core->MoveViewportTo( xp * MAP_MULT / MAP_DIV, yp * MAP_MULT / MAP_DIV, false ); + core->timer->SetMoveViewPort( xp * MAP_MULT / MAP_DIV, yp * MAP_MULT / MAP_DIV, 0, false ); } /** Mouse Button Down */ Modified: gemrb/trunk/gemrb/plugins/Core/TileOverlay.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/TileOverlay.cpp 2007-04-13 20:09:06 UTC (rev 4591) +++ gemrb/trunk/gemrb/plugins/Core/TileOverlay.cpp 2007-04-14 11:49:04 UTC (rev 4592) @@ -74,7 +74,7 @@ bump = true; } if( bump ) { - core->MoveViewportTo( vp.x, vp.y, false ); + core->timer->SetMoveViewPort( vp.x, vp.y, 0, false ); } // determine which tiles are visible Modified: gemrb/trunk/gemrb/plugins/Core/Video.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Video.h 2007-04-13 20:09:06 UTC (rev 4591) +++ gemrb/trunk/gemrb/plugins/Core/Video.h 2007-04-14 11:49:04 UTC (rev 4592) @@ -132,7 +132,7 @@ virtual Sprite2D* GetScreenshot( Region r ) = 0; virtual Region GetViewport(void) = 0; virtual void SetViewport(int x, int y, unsigned int w, unsigned int h) = 0; - virtual void MoveViewportTo(int x, int y, bool center) = 0; + virtual void MoveViewportTo(int x, int y) = 0; virtual void ConvertToVideoFormat(Sprite2D* sprite) = 0; /** No descriptions */ virtual void SetPalette(Sprite2D* spr, Palette* pal) = 0; Modified: gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-13 20:09:06 UTC (rev 4591) +++ gemrb/trunk/gemrb/plugins/PSTOpcodes/PSTOpc.cpp 2007-04-14 11:49:04 UTC (rev 4592) @@ -346,10 +346,10 @@ } //0xcd fx_move_view -int fx_move_view (Actor* /*Owner*/, Actor* target, Effect* fx) +int fx_move_view (Actor* /*Owner*/, Actor* /*target*/, Effect* fx) { - if (0) printf( "fx_move_view (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); - core->MoveViewportTo( target->Pos.x, target->Pos.y, true ); + if (0) printf( "fx_move_view (%2d): Speed: %d\n", fx->Opcode, fx->Parameter1 ); + core->timer->SetMoveViewPort( fx->PosX, fx->PosY, fx->Parameter1, true); return FX_NOT_APPLIED; } Modified: gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.cpp 2007-04-13 20:09:06 UTC (rev 4591) +++ gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.cpp 2007-04-14 11:49:04 UTC (rev 4592) @@ -129,7 +129,7 @@ printStatus( "OK", LIGHT_GREEN ); SDL_LockSurface( extra ); long val = SDL_MapRGBA( extra->format, fadeColor.r, fadeColor.g, fadeColor.b, 0 ); - SDL_FillRect( extra, NULL, val ); + SDL_FillRect( extra, NULL, val ); SDL_UnlockSurface( extra ); SDL_FreeSurface( tmp ); printMessage( "SDLVideo", "CreateDisplay...", WHITE ); @@ -484,7 +484,7 @@ if (dither) { unsigned char* pix = line + lt; unsigned char* end = line + rt; - + if ((lt + xoff + sy + yoff) % 2) pix++; // CHECKME: aliasing? for (; pix < end; pix += 2) *pix = 1; @@ -495,7 +495,7 @@ } line += sc->Width; } - } + } } @@ -604,7 +604,7 @@ unsigned char *newpixels = (unsigned char*) malloc( sprite->Width*sprite->Height ); SDL_LockSurface( tmp ); - memcpy(newpixels, sprite->pixels, sprite->Width*sprite->Height); + memcpy(newpixels, sprite->pixels, sprite->Width*sprite->Height); dest = CreateSprite8(sprite->Width, sprite->Height, 8, newpixels, tmp->format->palette->colors, true, 0); SDL_UnlockSurface( tmp ); @@ -757,7 +757,7 @@ #define ALREADYCLIPPED #define SPECIALPIXEL -#define FLIP +#define FLIP #define HFLIP_CONDITIONAL data->flip_hor #define VFLIP_CONDITIONAL data->flip_ver #define RLE data->RLE @@ -828,7 +828,7 @@ drect.x = x - spr->XPos - Viewport.x; drect.y = y - spr->YPos - Viewport.y; } - + if (clip) { if (drect.x + spr->Width <= clip->x) return; @@ -884,7 +884,7 @@ #define SPECIALPIXEL #undef BPP16 -#define FLIP +#define FLIP #define HFLIP_CONDITIONAL data->flip_hor #define VFLIP_CONDITIONAL data->flip_ver #define RLE data->RLE @@ -1028,7 +1028,7 @@ unsigned int remflags = flags & ~(BLIT_MIRRORX | BLIT_MIRRORY); if (remflags & BLIT_NOSHADOW) remflags &= ~BLIT_TRANSSHADOW; -#define FLIP +#define FLIP #define HFLIP_CONDITIONAL hflip #define VFLIP_CONDITIONAL vflip #define RLE data->RLE @@ -1190,7 +1190,7 @@ // printf("Unoptimized blit: %04X\n", flags); -#define SPECIALPIXEL int ia=0; if ((remflags & BLIT_HALFTRANS) || (p == 1 && (remflags & BLIT_TRANSSHADOW))) ia = 1; if (p == 1 && (remflags & BLIT_NOSHADOW)) { } else +#define SPECIALPIXEL int ia=0; if ((remflags & BLIT_HALFTRANS) || (p == 1 && (remflags & BLIT_TRANSSHADOW))) ia = 1; if (p == 1 && (remflags & BLIT_NOSHADOW)) { } else #define CUSTOMBLENDING #define RVALUE(r,g,b) (r) @@ -1246,7 +1246,7 @@ #define BPP16 #include "SDLVideoDriver.inl" } - } + } } #undef PALETTE_ALPHA } else { @@ -1291,7 +1291,7 @@ #define BPP16 #include "SDLVideoDriver.inl" } - } + } } } @@ -1388,13 +1388,8 @@ Viewport.h = h; } -void SDLVideoDriver::MoveViewportTo(int x, int y, bool center) +void SDLVideoDriver::MoveViewportTo(int x, int y) { - if (center) { - x -= ( Viewport.w / 2 ); - y -= ( Viewport.h / 2 ); - } - if (x != Viewport.x || y != Viewport.y) { core->GetSoundMgr()->UpdateViewportPos( (x - xCorr) + disp->w / 2, (y - yCorr) + disp->h / 2 ); Viewport.x = x; @@ -1638,8 +1633,8 @@ } /* - * Draws horizontal line. When clipped=true, it draws the line relative - * to Area origin and clips it by Area viewport borders, + * Draws horizontal line. When clipped=true, it draws the line relative + * to Area origin and clips it by Area viewport borders, * else it draws relative to screen origin and ignores the vieport */ void SDLVideoDriver::DrawHLine(short x1, short y, short x2, Color& color, bool clipped) @@ -1654,13 +1649,13 @@ y -= Viewport.y; x2 -= Viewport.x; } - for ( ; x1 <= x2 ; x1++ ) + for ( ; x1 <= x2 ; x1++ ) SetPixel( x1, y, color, clipped ); } /* - * Draws vertical line. When clipped=true, it draws the line relative - * to Area origin and clips it by Area viewport borders, + * Draws vertical line. When clipped=true, it draws the line relative + * to Area origin and clips it by Area viewport borders, * else it draws relative to screen origin and ignores the vieport */ void SDLVideoDriver::DrawVLine(short x, short y1, short y2, Color& color, bool clipped) @@ -1676,7 +1671,7 @@ y2 -= Viewport.y; } - for ( ; y1 <= y2 ; y1++ ) + for ( ; y1 <= y2 ; y1++ ) SetPixel( x, y1, color, clipped ); } @@ -1695,7 +1690,7 @@ if (abs( shortLen ) > abs( longLen )) { int swap = shortLen; shortLen = longLen; - longLen = swap; + longLen = swap; yLonger = true; } int decInc; @@ -1709,14 +1704,14 @@ if (longLen > 0) { longLen += y1; for (int j = 0x8000 + ( x1 << 16 ); y1 <= longLen; ++y1) { - SetPixel( j >> 16, y1, color, clipped ); + SetPixel( j >> 16, y1, color, clipped ); j += decInc; } return; } longLen += y1; for (int j = 0x8000 + ( x1 << 16 ); y1 >= longLen; --y1) { - SetPixel( j >> 16, y1, color, clipped ); + SetPixel( j >> 16, y1, color, clipped ); j -= decInc; } return; @@ -1901,7 +1896,7 @@ if (rt > Viewport.w) rt = Viewport.w; if (lt >= rt) { line += backBuf->pitch; continue; } // clipped - + // Draw a 50% alpha line from (y,lt) to (y,rt) if (backBuf->format->BytesPerPixel == 2) { @@ -2020,7 +2015,7 @@ dest->YPos = sprite->Height - sprite->YPos; else dest->YPos = sprite->YPos; - + return dest; } @@ -2055,7 +2050,7 @@ else dest->XPos = sprite->XPos; dest->YPos = sprite->YPos; - + return dest; } @@ -2170,7 +2165,7 @@ else if(b<0) b=0; fadeColor.b=b; long val = SDL_MapRGBA( extra->format, fadeColor.r, fadeColor.g, fadeColor.b, fadeColor.a ); - SDL_FillRect( extra, NULL, val ); + SDL_FillRect( extra, NULL, val ); } void SDLVideoDriver::SetFadePercent(int percent) @@ -2208,8 +2203,8 @@ void SDLVideoDriver::GetMousePos(int &x, int &y) { - x=CursorPos.x; - y=CursorPos.y; + x=CursorPos.x; + y=CursorPos.y; } void SDLVideoDriver::MouseMovement(int x, int y) @@ -2289,7 +2284,7 @@ void SDLVideoDriver::showFrame(unsigned char* buf, unsigned int bufw, unsigned int bufh, unsigned int sx, unsigned int sy, unsigned int w, - unsigned int h, unsigned int dstx, unsigned int dsty, + unsigned int h, unsigned int dstx, unsigned int dsty, int g_truecolor, unsigned char *pal, ieDword titleref) { int i; @@ -2384,5 +2379,5 @@ // FIXME:SetGammaRamp doesn't seem to work void SDLVideoDriver::SetGamma(int brightness, int /*contrast*/) { - SDL_SetGamma(0.8+brightness/50.0,0.8+brightness/50.0,0.8+brightness/50.0); + SDL_SetGamma(0.8+brightness/50.0,0.8+brightness/50.0,0.8+brightness/50.0); } Modified: gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.h =================================================================== --- gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.h 2007-04-13 20:09:06 UTC (rev 4591) +++ gemrb/trunk/gemrb/plugins/SDLVideo/SDLVideoDriver.h 2007-04-14 11:49:04 UTC (rev 4592) @@ -98,7 +98,7 @@ Sprite2D* GetScreenshot( Region r ); Region GetViewport(void); void SetViewport(int x, int y, unsigned int w, unsigned int h); - void MoveViewportTo(int x, int y, bool center); + void MoveViewportTo(int x, int y); void ConvertToVideoFormat(Sprite2D* sprite); /** No descriptions */ void SetPalette(Sprite2D* spr, Palette* pal); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-04-18 21:04:56
|
Revision: 4603 http://gemrb.svn.sourceforge.net/gemrb/?rev=4603&view=rev Author: avenger_teambg Date: 2007-04-18 14:04:57 -0700 (Wed, 18 Apr 2007) Log Message: ----------- fixed a few problems which made spellcasting impossible CharAnimations: removed a level of indentation Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Actions.cpp gemrb/trunk/gemrb/plugins/Core/Actor.cpp gemrb/trunk/gemrb/plugins/Core/Actor.h gemrb/trunk/gemrb/plugins/Core/CharAnimations.cpp gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp gemrb/trunk/gemrb/plugins/Core/GameControl.cpp gemrb/trunk/gemrb/plugins/Core/Interface.cpp gemrb/trunk/gemrb/plugins/Core/Spell.cpp gemrb/trunk/gemrb/plugins/Core/Spell.h gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp Modified: gemrb/trunk/gemrb/plugins/Core/Actions.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-04-18 20:57:24 UTC (rev 4602) +++ gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-04-18 21:04:57 UTC (rev 4603) @@ -2075,7 +2075,9 @@ { ieResRef spellres; +printf("Spell casting\n"); if (!ResolveSpellName( spellres, parameters) ) { +printf("failed to resolve\n"); Sender->ReleaseCurrentAction(); return; } @@ -2088,11 +2090,12 @@ if (Sender->Type == ST_ACTOR) { Actor *actor = (Actor *) Sender; actor->SetStance (IE_ANI_CAST); + actor->CastSpell (spellres, tar, true); } Point s,d; GetPositionFromScriptable( Sender, s, false ); GetPositionFromScriptable( tar, d, false ); - printf( "Spell from [%d,%d] to [%d,%d]\n", s.x, s.y, d.x, d.y ); +printf( "Spell from [%d,%d] to [%d,%d]\n", s.x, s.y, d.x, d.y ); //this might be bad Sender->ReleaseCurrentAction(); } @@ -2115,6 +2118,7 @@ if (Sender->Type == ST_ACTOR) { Actor *actor = (Actor *) Sender; actor->SetStance (IE_ANI_CAST); + actor->CastSpell (spellres, tar, false); } Point s,d; GetPositionFromScriptable( Sender, s, false ); Modified: gemrb/trunk/gemrb/plugins/Core/Actor.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-04-18 20:57:24 UTC (rev 4602) +++ gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-04-18 21:04:57 UTC (rev 4603) @@ -3039,11 +3039,14 @@ } Projectile *pro = itm->GetProjectile(header); - pro->SetCaster(globalID); - GetCurrentArea()->AddProjectile(pro, Pos, target); ChargeItem(slot, header, item, itm, silent); core->FreeItem(itm,item->ItemResRef, false); - return true; + if (pro) { + pro->SetCaster(globalID); + GetCurrentArea()->AddProjectile(pro, Pos, target); + return true; + } + return false; } bool Actor::UseItem(int slot, ieDword header, Scriptable* target, bool silent) @@ -3062,13 +3065,14 @@ return false; } Projectile *pro = itm->GetProjectile(header); + ChargeItem(slot, header, item, itm, silent); + core->FreeItem(itm,item->ItemResRef, false); if (pro) { pro->SetCaster(globalID); GetCurrentArea()->AddProjectile(pro, Pos, tar->globalID); + return true; } - ChargeItem(slot, header, item, itm, silent); - core->FreeItem(itm,item->ItemResRef, false); - return true; + return false; } void Actor::ChargeItem(int slot, ieDword header, CREItem *item, Item *itm, bool silent) @@ -3096,45 +3100,61 @@ } } -bool Actor::CastSpellPoint( ieResRef SpellResRef, Point &target ) +bool Actor::CastSpellPoint( ieResRef SpellResRef, Point &target, bool deplete ) { - if (! spellbook.HaveSpell( SpellResRef, HS_DEPLETE )) { - return false; + if (deplete) { + if (! spellbook.HaveSpell( SpellResRef, HS_DEPLETE )) { + SetStance(IE_ANI_READY); + return false; + } } + SetStance(IE_ANI_CONJURE); Spell* spl = core->GetSpell( SpellResRef ); //cfb - EffectQueue *fxqueue=spl->GetEffectBlock(-1); + int dummy; + EffectQueue *fxqueue=spl->GetEffectBlock(-1, dummy); fxqueue->SetOwner(this); fxqueue->ApplyAllEffects(this); //spell Projectile *pro=spl->GetProjectile(GetXPLevel(true)); - pro->SetCaster(globalID); - GetCurrentArea()->AddProjectile(pro, Pos, target); - return true; + if (pro) { + pro->SetCaster(globalID); + GetCurrentArea()->AddProjectile(pro, Pos, target); + return true; + } + return false; } -bool Actor::CastSpell( ieResRef SpellResRef, Scriptable* target ) +bool Actor::CastSpell( ieResRef SpellResRef, Scriptable* target, bool deplete ) { - if (! spellbook.HaveSpell( SpellResRef, HS_DEPLETE )) { - return false; + if (target->Type!=ST_ACTOR) { + return CastSpellPoint(SpellResRef, target->Pos, deplete); } - if (target->Type!=ST_ACTOR) { - return CastSpellPoint(SpellResRef, target->Pos); + if (deplete) { + if (! spellbook.HaveSpell( SpellResRef, HS_DEPLETE )) { + SetStance(IE_ANI_READY); + return false; + } } + SetStance(IE_ANI_CONJURE); Actor *Target = (Actor *) target; Spell* spl = core->GetSpell( SpellResRef ); //cfb - EffectQueue *fxqueue=spl->GetEffectBlock(-1); + int dummy; + EffectQueue *fxqueue=spl->GetEffectBlock(-1, dummy); fxqueue->SetOwner(this); fxqueue->ApplyAllEffects(this); //spell Projectile *pro=spl->GetProjectile(GetXPLevel(true)); - pro->SetCaster(globalID); - GetCurrentArea()->AddProjectile(pro, Pos, Target->globalID); - return true; + if (pro) { + pro->SetCaster(globalID); + GetCurrentArea()->AddProjectile(pro, Pos, Target->globalID); + return true; + } + return false; } bool Actor::IsReverseToHit() Modified: gemrb/trunk/gemrb/plugins/Core/Actor.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-04-18 20:57:24 UTC (rev 4602) +++ gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-04-18 21:04:57 UTC (rev 4603) @@ -438,8 +438,8 @@ /* Deducts a charge from an item */ void ChargeItem(int slot, ieDword header, CREItem *item, Item *itm, bool silent); /* actor casts spell */ - bool CastSpellPoint( ieResRef SpellResRef, Point &Target ); - bool CastSpell( ieResRef SpellResRef, Scriptable* Target ); + bool CastSpellPoint( ieResRef SpellResRef, Point &Target, bool deplete ); + bool CastSpell( ieResRef SpellResRef, Scriptable* Target, bool deplete ); /* If it returns true, then default AC=10 and the lesser the better */ bool IsReverseToHit(); void InitButtons(ieDword cls); Modified: gemrb/trunk/gemrb/plugins/Core/CharAnimations.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/CharAnimations.cpp 2007-04-18 20:57:24 UTC (rev 4602) +++ gemrb/trunk/gemrb/plugins/Core/CharAnimations.cpp 2007-04-18 21:04:57 UTC (rev 4603) @@ -1921,39 +1921,40 @@ { unsigned long time = core->GetGame()->Ticks; - if (time - lastModUpdate > 40) { - if (time - lastModUpdate > 400) lastModUpdate = time - 40; + if (time - lastModUpdate <= 40) + return; - int inc = (time - lastModUpdate)/40; - bool change[4] = { false, false, false, false }; - if (GlobalColorMod.type != RGBModifier::NONE && - GlobalColorMod.speed > 0) - { - GlobalColorMod.phase += inc; - change[0] = change[1] = change[2] = change[3] = true; + if (time - lastModUpdate > 400) lastModUpdate = time - 40; - // reset if done - if (GlobalColorMod.phase > 2*GlobalColorMod.speed) { - GlobalColorMod.type = RGBModifier::NONE; - GlobalColorMod.phase = 0; - GlobalColorMod.speed = 0; - } + int inc = (time - lastModUpdate)/40; + bool change[4] = { false, false, false, false }; + if (GlobalColorMod.type != RGBModifier::NONE && + GlobalColorMod.speed > 0) + { + GlobalColorMod.phase += inc; + change[0] = change[1] = change[2] = change[3] = true; + + // reset if done + if (GlobalColorMod.phase > 2*GlobalColorMod.speed) { + GlobalColorMod.type = RGBModifier::NONE; + GlobalColorMod.phase = 0; + GlobalColorMod.speed = 0; } + } - for (int i = 0; i < 32; ++i) { - if (ColorMods[i].type != RGBModifier::NONE && - ColorMods[i].speed > 0) - { - ColorMods[i].phase += inc; - change[i>>3] = true; - } + for (int i = 0; i < 32; ++i) { + if (ColorMods[i].type != RGBModifier::NONE && + ColorMods[i].speed > 0) + { + ColorMods[i].phase += inc; + change[i>>3] = true; } + } - if (change[0]) SetupColors(PAL_MAIN); - if (change[1]) SetupColors(PAL_WEAPON); - if (change[2]) SetupColors(PAL_OFFHAND); - if (change[3]) SetupColors(PAL_HELMET); + if (change[0]) SetupColors(PAL_MAIN); + if (change[1]) SetupColors(PAL_WEAPON); + if (change[2]) SetupColors(PAL_OFFHAND); + if (change[3]) SetupColors(PAL_HELMET); - lastModUpdate += inc*40; - } + lastModUpdate += inc*40; } Modified: gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp 2007-04-18 20:57:24 UTC (rev 4602) +++ gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp 2007-04-18 21:04:57 UTC (rev 4603) @@ -101,7 +101,7 @@ if (timingmode>=MAX_TIMING_MODE) return false; return fx_instant[timingmode]; } -// 0 1 2 3 4 5 6 7 8 +// 0 1 2 3 4 5 6 7 8 9 10 static bool fx_relative[MAX_TIMING_MODE]={true,false,false,true,true,true,false,false,false,false,false}; inline bool NeedPrepare(ieByte timingmode) @@ -642,14 +642,14 @@ //magic immunity ieDword val = actor->GetStat(IE_RESISTMAGIC); if (fx->random_value < val) { - return false; + return true; } //opcode immunity if (actor->fxqueue.HasEffectWithParam(fx_opcode_immunity_ref, fx->Opcode) ) { - return false; + return true; } if (actor->fxqueue.HasEffectWithParam(fx_opcode_immunity2_ref, fx->Opcode) ) { - return false; + return true; } /* opcode bouncing isn't implemented? //opcode bouncing @@ -672,12 +672,11 @@ if (saved) { if (fx->IsSaveForHalfDamage) { fx->Parameter1/=2; + } else { + return true; } - else { - return false; - } } - return true; + return false; } // this function is called two different ways Modified: gemrb/trunk/gemrb/plugins/Core/GameControl.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameControl.cpp 2007-04-18 20:57:24 UTC (rev 4602) +++ gemrb/trunk/gemrb/plugins/Core/GameControl.cpp 2007-04-18 21:04:57 UTC (rev 4603) @@ -591,7 +591,7 @@ case 'c': if (game->selected.size() > 0 && lastActor) { Actor *src = game->selected[0]; - bool res = src->CastSpell( "SPWI207", lastActor ); + bool res = src->CastSpell( "SPWI207", lastActor, false ); printf( "Cast Spell: %d\n", res ); } break; @@ -944,11 +944,12 @@ { char Tmp[40]; - if (!spellCount) spellOrItem = 0; - if (!spellOrItem) return; //not casting or using an own item + if (!spellCount) { + target_mode = TARGET_MODE_NONE; + return; //not casting or using an own item + } spellCount--; - if (!spellOrItem) return; //not casting or using an own item - if (spellOrItem>0) { + if (spellOrItem>=0) { CREMemorizedSpell *si; //spell casting at target si = source->spellbook.GetMemorizedSpell(spellOrItem, spellSlot, spellIndex); @@ -959,7 +960,6 @@ } source->AddAction( GenerateAction( Tmp) ); if (!spellCount) { - spellOrItem = 0; target_mode = TARGET_MODE_NONE; } } @@ -968,8 +968,10 @@ { char Tmp[40]; - if (!spellCount) spellOrItem = 0; - if (!spellOrItem) return; //not casting or using an own item + if (!spellCount) { + target_mode = TARGET_MODE_NONE; + return; //not casting or using an own item + } spellCount--; if (spellOrItem>0) { sprintf(Tmp, "NIDSpecial6()"); @@ -979,7 +981,7 @@ } Action* action = GenerateActionDirect( Tmp, tgt); source->AddAction( action ); - if (spellOrItem>0) + if (spellOrItem>=0) { CREMemorizedSpell *si; //spell casting at target @@ -992,7 +994,6 @@ action->int1Parameter=spellIndex; } if (!spellCount) { - spellOrItem = 0; target_mode = TARGET_MODE_NONE; } } @@ -1016,7 +1017,7 @@ { char Tmp[256]; - if (spellOrItem) { + if (spellCount) { //we'll get the container back from the coordinates TryToCast(actor, container->Pos); return; @@ -1032,7 +1033,7 @@ { char Tmp[256]; - if (spellOrItem) { + if (spellCount) { //we'll get the door back from the coordinates TryToCast(actor, door->Pos); return; @@ -1053,7 +1054,7 @@ bool GameControl::HandleActiveRegion(InfoPoint *trap, Actor * actor, Point &p) { - if (spellOrItem) { + if (spellCount) { //we'll get the active region from the coordinates (if needed) TryToCast(actor, p); //don't bother with this region further @@ -1190,7 +1191,7 @@ //just a single actor, no formation if (game->selected.size()==1) { //the player is using an item or spell on the ground - if (spellOrItem) { + if (spellCount) { TryToCast(core->GetFirstSelectedPC(), p); return; } @@ -1253,7 +1254,7 @@ //we shouldn't zero this for two reasons in case of spell or item //1. there could be multiple targets //2. the target mode is important - if (!spellOrItem) { + if (!spellCount) { target_mode = TARGET_MODE_NONE; } Modified: gemrb/trunk/gemrb/plugins/Core/Interface.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Interface.cpp 2007-04-18 20:57:24 UTC (rev 4602) +++ gemrb/trunk/gemrb/plugins/Core/Interface.cpp 2007-04-18 21:04:57 UTC (rev 4603) @@ -4865,7 +4865,8 @@ if (!level) { level = 1; } - EffectQueue *fxqueue = spell->GetEffectBlock(level); + int dummy; //the extended header # + EffectQueue *fxqueue = spell->GetEffectBlock(level, dummy); //check effect immunities int res = fxqueue->CheckImmunity ( actor ); @@ -4888,7 +4889,8 @@ if (!level) { level = 1; } - EffectQueue *fxqueue = spell->GetEffectBlock(level); + int dummy; + EffectQueue *fxqueue = spell->GetEffectBlock(level, dummy); fxqueue->SetOwner( caster ); //add effect to area??? delete fxqueue; Modified: gemrb/trunk/gemrb/plugins/Core/Spell.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spell.cpp 2007-04-18 20:57:24 UTC (rev 4602) +++ gemrb/trunk/gemrb/plugins/Core/Spell.cpp 2007-04-18 21:04:57 UTC (rev 4603) @@ -47,18 +47,18 @@ //-1 will return cfb //0 will always return first spell block //otherwise set to caster level -EffectQueue *Spell::GetEffectBlock(int level) const +EffectQueue *Spell::GetEffectBlock(int level, int &block_index) const { Effect *features; int count; + block_index=0; //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; @@ -87,15 +87,15 @@ return fxqueue; } -Projectile *Spell::GetProjectile(int header) const +Projectile *Spell::GetProjectile(int level) const { - SPLExtHeader *eh = GetExtHeader(header); - if (!eh) { - return NULL; + int ext_block; + EffectQueue *fx = GetEffectBlock(level, ext_block); + if (fx->GetEffectsCount()) { + Projectile *pro = core->GetProjectileServer()->GetProjectileByIndex(ext_headers[ext_block].ProjectileAnimation); + pro->SetEffects(fx); + return pro; } - EffectQueue *fx = GetEffectBlock(header); - Projectile *pro = core->GetProjectileServer()->GetProjectileByIndex(eh->ProjectileAnimation); - pro->SetEffects(fx); - return pro; + return NULL; } Modified: gemrb/trunk/gemrb/plugins/Core/Spell.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spell.h 2007-04-18 20:57:24 UTC (rev 4602) +++ gemrb/trunk/gemrb/plugins/Core/Spell.h 2007-04-18 21:04:57 UTC (rev 4603) @@ -154,9 +154,9 @@ return ext_headers+which; } //-1 will return the cfb - EffectQueue *GetEffectBlock(int wanted_level) const; + EffectQueue *GetEffectBlock(int wanted_level, int &block_index) const; //returns a projectile created from an extended header - Projectile *GetProjectile(int header) const; + Projectile *GetProjectile(int wanted_level) const; }; #endif // ! SPELL_H Modified: gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp 2007-04-18 20:57:24 UTC (rev 4602) +++ gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp 2007-04-18 21:04:57 UTC (rev 4603) @@ -578,6 +578,9 @@ } SPLExtHeader *ext_header = spl->ext_headers+ehc; array[pos].headerindex = ehc; + array[pos].level = sm->Level; + array[pos].type = sm->Type; + array[pos].count = k; array[pos].SpellForm = ext_header->SpellForm; memcpy(array[pos].MemorisedIcon, ext_header->MemorisedIcon,sizeof(ieResRef) ); array[pos].Target = ext_header->Target; @@ -586,7 +589,6 @@ array[pos].Projectile = ext_header->ProjectileAnimation; array[pos].CastingTime = (ieWord) ext_header->CastingTime; array[pos].strref = spl->SpellName; - array[pos].count = 1; pos++; core->FreeSpell(spl, slot->SpellResRef, false); } Modified: gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-04-18 20:57:24 UTC (rev 4602) +++ gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-04-18 21:04:57 UTC (rev 4603) @@ -7472,13 +7472,13 @@ actor->CastSpell(spelldata.spellname, NULL, true); break; case TARGET_AREA: - core->GetGameControl()->SetupCasting(spelldata.type, spelldata.level, spelldata.headerindex, actor, GA_POINT, spelldata.TargetNumber); + core->GetGameControl()->SetupCasting(spelldata.type, spelldata.level, spelldata.count, actor, GA_POINT, spelldata.TargetNumber); break; case TARGET_CREA: - core->GetGameControl()->SetupCasting(spelldata.type, spelldata.level, spelldata.headerindex, actor, GA_NO_DEAD, spelldata.TargetNumber); + core->GetGameControl()->SetupCasting(spelldata.type, spelldata.level, spelldata.count, actor, GA_NO_DEAD, spelldata.TargetNumber); break; case TARGET_DEAD: - core->GetGameControl()->SetupCasting(spelldata.type, spelldata.level, spelldata.headerindex, actor, 0, spelldata.TargetNumber); + core->GetGameControl()->SetupCasting(spelldata.type, spelldata.level, spelldata.count, actor, 0, spelldata.TargetNumber); break; default: printMessage("GUIScript", "Unhandled target type!", LIGHT_RED ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-04-22 17:02:20
|
Revision: 4605 http://gemrb.svn.sourceforge.net/gemrb/?rev=4605&view=rev Author: avenger_teambg Date: 2007-04-22 10:02:17 -0700 (Sun, 22 Apr 2007) Log Message: ----------- implemented spellinfo grouping Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Actions.cpp gemrb/trunk/gemrb/plugins/Core/GameScript.cpp gemrb/trunk/gemrb/plugins/Core/GameScript.h 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-19 20:34:21 UTC (rev 4604) +++ gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-04-22 17:02:17 UTC (rev 4605) @@ -2100,6 +2100,34 @@ Sender->ReleaseCurrentAction(); } +void GameScript::SpellPoint(Scriptable* Sender, Action* parameters) +{ + ieResRef spellres; + +printf("Spell casting\n"); + if (!ResolveSpellName( spellres, parameters) ) { +printf("failed to resolve\n"); + Sender->ReleaseCurrentAction(); + return; + } + + Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); + if (!tar) { + Sender->ReleaseCurrentAction(); + return; + } + if (Sender->Type == ST_ACTOR) { + Actor *actor = (Actor *) Sender; + actor->SetStance (IE_ANI_CAST); + actor->CastSpellPoint (spellres, parameters->pointParameter, true); + } + Point s; + GetPositionFromScriptable( Sender, s, false ); + printf( "Spell from [%d,%d] to [%d,%d]\n", s.x, s.y, parameters->pointParameter.x, parameters->pointParameter.y ); + //this might be bad + Sender->ReleaseCurrentAction(); +} + //it is unsure how the ForceSpell actions differ void GameScript::ForceSpell(Scriptable* Sender, Action* parameters) { @@ -2128,6 +2156,32 @@ Sender->ReleaseCurrentAction(); } +void GameScript::ForceSpellPoint(Scriptable* Sender, Action* parameters) +{ + ieResRef spellres; + + if (!ResolveSpellName( spellres, parameters) ) { + Sender->ReleaseCurrentAction(); + return; + } + + Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); + if (!tar) { + Sender->ReleaseCurrentAction(); + return; + } + if (Sender->Type == ST_ACTOR) { + Actor *actor = (Actor *) Sender; + actor->SetStance (IE_ANI_CAST); + actor->CastSpellPoint (spellres, parameters->pointParameter, false); + } + Point s; + GetPositionFromScriptable( Sender, s, false ); + printf( "ForceSpell from [%d,%d] to [%d,%d]\n", s.x, s.y, parameters->pointParameter.x, parameters->pointParameter.y ); + //this might be bad + Sender->ReleaseCurrentAction(); +} + void GameScript::ReallyForceSpell(Scriptable* Sender, Action* parameters) { ieResRef spellres; Modified: gemrb/trunk/gemrb/plugins/Core/GameScript.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameScript.cpp 2007-04-19 20:34:21 UTC (rev 4604) +++ gemrb/trunk/gemrb/plugins/Core/GameScript.cpp 2007-04-22 17:02:17 UTC (rev 4605) @@ -546,6 +546,7 @@ {"forcehide", GameScript::ForceHide, 0}, {"forceleavearealua", GameScript::ForceLeaveAreaLUA, 0}, {"forcespell", GameScript::ForceSpell, AF_BLOCKING}, + {"forcespellpoint", GameScript::ForceSpellPoint, AF_BLOCKING}, {"forceusecontainer", GameScript::ForceUseContainer,AF_BLOCKING}, {"formation", GameScript::Formation, AF_BLOCKING}, {"fullheal", GameScript::FullHeal, 0}, @@ -793,7 +794,9 @@ {"spawnptactivate", GameScript::SpawnPtActivate, 0}, {"spawnptdeactivate", GameScript::SpawnPtDeactivate, 0}, {"spawnptspawn", GameScript::SpawnPtSpawn, 0}, + {"spell", GameScript::Spell, AF_BLOCKING}, {"spellhiteffectsprite", GameScript::SpellHitEffectSprite, 0}, + {"spellpoint", GameScript::SpellPoint, AF_BLOCKING}, {"startcutscene", GameScript::StartCutScene, 0}, {"startcutsceneex", GameScript::StartCutScene, 0}, //pst (unknown) {"startcutscenemode", GameScript::StartCutSceneMode, 0}, Modified: gemrb/trunk/gemrb/plugins/Core/GameScript.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameScript.h 2007-04-19 20:34:21 UTC (rev 4604) +++ gemrb/trunk/gemrb/plugins/Core/GameScript.h 2007-04-22 17:02:17 UTC (rev 4605) @@ -1103,6 +1103,7 @@ static void ForceHide(Scriptable* Sender, Action* parameters); static void ForceLeaveAreaLUA(Scriptable* Sender, Action* parameters); static void ForceSpell(Scriptable* Sender, Action* parameters); + static void ForceSpellPoint(Scriptable* Sender, Action* parameters); static void ForceUseContainer(Scriptable* Sender, Action* parameters); static void Formation(Scriptable* Sender, Action* parameters); static void FullHeal(Scriptable* Sender, Action* parameters); @@ -1323,6 +1324,7 @@ static void SpawnPtSpawn(Scriptable* Sender, Action* parameters); static void Spell(Scriptable* Sender, Action* parameters); static void SpellHitEffectSprite(Scriptable* Sender, Action* parameters); + static void SpellPoint(Scriptable* Sender, Action* parameters); static void StartCutScene(Scriptable* Sender, Action* parameters); static void StartCutSceneMode(Scriptable* Sender, Action* parameters); static void StartDialogue(Scriptable* Sender, Action* parameters); Modified: gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp 2007-04-19 20:34:21 UTC (rev 4604) +++ gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp 2007-04-22 17:02:17 UTC (rev 4605) @@ -310,7 +310,7 @@ return true; } -CREKnownSpell* Spellbook::GetKnownSpell(int type, unsigned int level, unsigned int index) +CREKnownSpell* Spellbook::GetKnownSpell(int type, unsigned int level, unsigned int index) const { if (type >= NUM_SPELL_TYPES || level >= GetSpellLevelCount(type) || index >= spells[type][level]->known_spells.size()) return NULL; @@ -336,7 +336,7 @@ return (unsigned int) spells[type][level]->memorized_spells.size(); } -CREMemorizedSpell* Spellbook::GetMemorizedSpell(int type, unsigned int level, unsigned int index) +CREMemorizedSpell* Spellbook::GetMemorizedSpell(int type, unsigned int level, unsigned int index) const { if (type >= NUM_SPELL_TYPES || level >= GetSpellLevelCount(type) || index >= spells[type][level]->memorized_spells.size()) return NULL; @@ -423,7 +423,7 @@ mem_spl->Flags = usable ? 1 : 0; // FIXME: is it all it's used for? sm->memorized_spells.push_back( mem_spl ); - + ClearSpellInfo(); return true; } @@ -437,6 +437,7 @@ if (*s == spell) { delete *s; (*sm)->memorized_spells.erase( s ); + ClearSpellInfo(); return true; } } @@ -526,6 +527,7 @@ bool Spellbook::ChargeSpell(CREMemorizedSpell* spl) { spl->Flags = 1; + ClearSpellInfo(); return true; } @@ -533,6 +535,7 @@ { if (spl->Flags) { spl->Flags = 0; + ClearSpellInfo(); return true; } return false; @@ -540,6 +543,7 @@ /* returns true if there are more item usages not fitting in given array */ /* FIXME: it should first build up a list and then return a subset */ +/* bool Spellbook::GetSpellInfo(SpellExtHeader *array, int type, int startindex, int count) { int pos = 0; @@ -580,7 +584,8 @@ array[pos].headerindex = ehc; array[pos].level = sm->Level; array[pos].type = sm->Type; - array[pos].count = k; + array[pos].slot = k; + array[pos].count = 1; array[pos].SpellForm = ext_header->SpellForm; memcpy(array[pos].MemorisedIcon, ext_header->MemorisedIcon,sizeof(ieResRef) ); array[pos].Target = ext_header->Target; @@ -598,7 +603,125 @@ return false; } - +*/ + +void Spellbook::ClearSpellInfo() +{ + size_t i = spellinfo.size(); + while(i--) { + delete spellinfo[i]; + } + spellinfo.clear(); +} + +bool Spellbook::GetSpellInfo(SpellExtHeader *array, int type, int startindex, int count) +{ + memset(array, 0, count * sizeof(SpellExtHeader) ); + if (spellinfo.size()==0) { + GenerateSpellInfo(); + } + int actual = 0; + bool ret = false; + for (unsigned int i = startindex; i<spellinfo.size(); i++) { + if ( !(type & (1<<spellinfo[i]->type)) ) { + continue; + } + if (actual>=count) { + ret = true; + break; + } + memcpy(array+actual, spellinfo[i], sizeof(SpellExtHeader)); + actual++; + } + return ret; +} + +// returns the size of spellinfo vector, if type is nonzero it is used as filter +// for example type==1 lists the number of different mage spells +unsigned int Spellbook::GetSpellInfoSize(int type) +{ + size_t i = spellinfo.size(); + if (!i) { + GenerateSpellInfo(); + i = spellinfo.size(); + } + if (type) { + return (unsigned int) i; + } + unsigned int count = 0; + while(i--) { + if (spellinfo[i]->type&type) { + count++; + } + } + return count; +} + +SpellExtHeader *Spellbook::FindSpellInfo(unsigned int level, unsigned int type, ieResRef spellname) +{ + size_t i = spellinfo.size(); + while(i--) { + if( (spellinfo[i]->level==level) && + (spellinfo[i]->type==type) && + !strnicmp(spellinfo[i]->spellname, spellname, 8)) { + return spellinfo[i]; + } + } + return NULL; +} + +// grouping the castable spells +void Spellbook::GenerateSpellInfo() +{ + ClearSpellInfo(); //just in case + for (int i = 0; i < NUM_SPELL_TYPES; i++) { + for (unsigned int j = 0; j < spells[i].size(); j++) { + CRESpellMemorization* sm = spells[i][j]; + + for (unsigned int k = 0; k < sm->memorized_spells.size(); k++) { + CREMemorizedSpell* slot = sm->memorized_spells[k]; + if (!slot) + continue; + if (!slot->Flags) + continue; + Spell *spl = core->GetSpell(slot->SpellResRef); + ieDword level = 0; + SpellExtHeader *seh = FindSpellInfo(sm->Level, sm->Type, slot->SpellResRef); + if (seh) { + seh->count++; + continue; + } + seh = new SpellExtHeader; + spellinfo.push_back( seh ); + + memcpy(seh->spellname, slot->SpellResRef, sizeof(ieResRef) ); + int ehc; + + for(ehc=0;ehc<spl->ExtHeaderCount-1;ehc++) { + if (level<spl->ext_headers[ehc+1].RequiredLevel) { + break; + } + } + SPLExtHeader *ext_header = spl->ext_headers+ehc; + seh->headerindex = ehc; + seh->level = sm->Level; + seh->type = sm->Type; + seh->slot = k; + seh->count = 1; + seh->SpellForm = ext_header->SpellForm; + memcpy(seh->MemorisedIcon, ext_header->MemorisedIcon,sizeof(ieResRef) ); + seh->Target = ext_header->Target; + seh->TargetNumber = ext_header->TargetNumber; + seh->Range = ext_header->Range; + seh->Projectile = ext_header->ProjectileAnimation; + seh->CastingTime = (ieWord) ext_header->CastingTime; + seh->strref = spl->SpellName; + core->FreeSpell(spl, slot->SpellResRef, false); + } + } + } +} + void Spellbook::dump() { unsigned int k; Modified: gemrb/trunk/gemrb/plugins/Core/Spellbook.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spellbook.h 2007-04-19 20:34:21 UTC (rev 4604) +++ gemrb/trunk/gemrb/plugins/Core/Spellbook.h 2007-04-22 17:02:17 UTC (rev 4605) @@ -117,6 +117,7 @@ ieDword count; ieDword type; //spelltype ieDword headerindex; + ieDword slot; //these come from the header ieByte SpellForm; ieResRef MemorisedIcon; @@ -138,9 +139,16 @@ class GEM_EXPORT Spellbook { private: std::vector<CRESpellMemorization*> *spells; + std::vector<SpellExtHeader*> spellinfo; /** Sets spell from memorized as 'already-cast' */ bool DepleteSpell(CREMemorizedSpell* spl); + /** regenerates the spellinfo list */ + void GenerateSpellInfo(); + /** invalidates the spellinfo list */ + void ClearSpellInfo(); + /** looks up the spellinfo list for an element */ + SpellExtHeader *FindSpellInfo(unsigned int level, unsigned int type, ieResRef name); public: Spellbook(); ~Spellbook(); @@ -164,10 +172,10 @@ void RemoveSpell(ieResRef ResRef); /** adds a spell to the book */ bool AddKnownSpell(int type, unsigned int level, CREKnownSpell *spl); - CREKnownSpell* GetKnownSpell(int type, unsigned int level, unsigned int index); + CREKnownSpell* GetKnownSpell(int type, unsigned int level, unsigned int index) const; unsigned int GetMemorizedSpellsCount(int type) const; unsigned int GetMemorizedSpellsCount(int type, unsigned int level) const; - CREMemorizedSpell* GetMemorizedSpell(int type, unsigned int level, unsigned int index); + CREMemorizedSpell* GetMemorizedSpell(int type, unsigned int level, unsigned int index) const; int GetMemorizableSpellsCount(int type, unsigned int level, bool bonus) const; void SetMemorizableSpellsCount(int Value, int type, unsigned int level, bool bonus); @@ -193,6 +201,9 @@ /** recharges all spells */ void ChargeAllSpells(); + /** returns the number of distinct spells (generates spellinfo) */ + unsigned int GetSpellInfoSize(int type); + /** lists spells of a type */ bool GetSpellInfo(SpellExtHeader *array, int type, int startindex, int count); /** Dumps spellbook to stdout for debugging */ Modified: gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-04-19 20:34:21 UTC (rev 4604) +++ gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-04-22 17:02:17 UTC (rev 4605) @@ -6957,16 +6957,23 @@ if (!SpellArray) { SpellArray = (SpellExtHeader *) malloc((GUIBT_COUNT) * sizeof (SpellExtHeader) ); } - bool more = actor->spellbook.GetSpellInfo(SpellArray, Type, Start, GUIBT_COUNT-(Start?1:0)); + int more = actor->spellbook.GetSpellInfo(SpellArray, Type, Start, GUIBT_COUNT-(Start?1:0)); int i; if (Start) { - more = true; + more |= 2; } if (more) { - PyObject *ret = SetActionIcon(wi,core->GetControl(wi, 0),ACT_LEFT,0); + int ci = core->GetControl(wi, 0); + PyObject *ret = SetActionIcon(wi, ci, ACT_LEFT, 0); if (!ret) { return RuntimeError("Cannot set action button!\n"); } + Button * btn = (Button *) GetControl(wi, ci, IE_GUI_BUTTON); + if (Start) { + btn->SetState(IE_GUI_BUTTON_UNPRESSED); + } else { + btn->SetState(IE_GUI_BUTTON_DISABLED); + } } //FIXME: this is a hardcoded resource (pst has no such one) @@ -6981,6 +6988,7 @@ int ci = core->GetControl(wi, i+(more?1:0) ); Button* btn = (Button *) GetControl( wi, ci, IE_GUI_BUTTON ); btn->SetEvent(IE_GUI_BUTTON_ON_PRESS,"SpellPressed"); + btn->SetState(IE_GUI_BUTTON_UNPRESSED); strcpy(btn->VarName,"Spell"); btn->Value = Start+i; @@ -7016,10 +7024,19 @@ } if (more) { - PyObject *ret = SetActionIcon(wi,core->GetControl(wi, i+1),ACT_RIGHT,i+1); + int ci = core->GetControl(wi, i+1); + PyObject *ret = SetActionIcon(wi, ci, ACT_RIGHT, i+1); if (!ret) { return RuntimeError("Cannot set action button!\n"); } + Button* btn = (Button *) GetControl( wi, ci, IE_GUI_BUTTON ); + if (more&1) { + btn->SetState(IE_GUI_BUTTON_UNPRESSED); + } else { + btn->SetState(IE_GUI_BUTTON_DISABLED); + btn->SetFlags(IE_GUI_BUTTON_NO_IMAGE, BM_SET); + btn->SetTooltip(NULL); + } } Py_INCREF( Py_None ); @@ -7085,7 +7102,7 @@ } else { type = 1<<IE_SPELL_TYPE_INNATE; } - if (!actor->spellbook.GetSpellInfo(NULL, type, 0, 0)) { + if (!actor->spellbook.GetSpellInfoSize(type)) { state = IE_GUI_BUTTON_DISABLED; } break; @@ -7097,7 +7114,7 @@ type = (1<<IE_SPELL_TYPE_INNATE)-1; } //returns true if there are ANY spells to cast - if (!actor->spellbook.GetSpellInfo(NULL, type, 0, 0)) { + if (!actor->spellbook.GetSpellInfoSize(type)) { state = IE_GUI_BUTTON_DISABLED; } break; @@ -7108,7 +7125,7 @@ type = 0; //no separate shapes in old spellbook } //returns true if there is ANY shape - if (!actor->spellbook.GetSpellInfo(NULL, type, 0, 0)) { + if (!actor->spellbook.GetSpellInfoSize(type)) { state = IE_GUI_BUTTON_DISABLED; } break; @@ -7121,7 +7138,7 @@ case ACT_BARDSONG: if (actor->spellbook.IsIWDSpellBook()) { type = 1<<IE_IWD2_SPELL_SONG; - if (!actor->spellbook.GetSpellInfo(NULL, type, 0, 0)) { + if (!actor->spellbook.GetSpellInfoSize(type)) { state = IE_GUI_BUTTON_DISABLED; } } else { @@ -7472,13 +7489,13 @@ actor->CastSpell(spelldata.spellname, NULL, true); break; case TARGET_AREA: - core->GetGameControl()->SetupCasting(spelldata.type, spelldata.level, spelldata.count, actor, GA_POINT, spelldata.TargetNumber); + core->GetGameControl()->SetupCasting(spelldata.type, spelldata.level, spelldata.slot, actor, GA_POINT, spelldata.TargetNumber); break; case TARGET_CREA: - core->GetGameControl()->SetupCasting(spelldata.type, spelldata.level, spelldata.count, actor, GA_NO_DEAD, spelldata.TargetNumber); + core->GetGameControl()->SetupCasting(spelldata.type, spelldata.level, spelldata.slot, actor, GA_NO_DEAD, spelldata.TargetNumber); break; case TARGET_DEAD: - core->GetGameControl()->SetupCasting(spelldata.type, spelldata.level, spelldata.count, actor, 0, spelldata.TargetNumber); + core->GetGameControl()->SetupCasting(spelldata.type, spelldata.level, spelldata.slot, actor, 0, spelldata.TargetNumber); break; default: printMessage("GUIScript", "Unhandled target type!", LIGHT_RED ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-04-28 07:32:51
|
Revision: 4612 http://gemrb.svn.sourceforge.net/gemrb/?rev=4612&view=rev Author: avenger_teambg Date: 2007-04-28 00:32:50 -0700 (Sat, 28 Apr 2007) Log Message: ----------- moved location parsing to SetColorMod, allowing full body rgb glow (used in iwd) Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Actor.cpp gemrb/trunk/gemrb/plugins/Core/Actor.h gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp gemrb/trunk/gemrb/plugins/IWDOpcodes/IWDOpc.cpp Modified: gemrb/trunk/gemrb/plugins/Core/Actor.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-04-24 16:34:56 UTC (rev 4611) +++ gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-04-28 07:32:50 UTC (rev 4612) @@ -2302,15 +2302,14 @@ */ } -void Actor::SetColorMod( int location, RGBModifier::Type type, int speed, - unsigned char r, unsigned char g, unsigned char b, - int phase) +void Actor::SetColorMod( ieByte location, RGBModifier::Type type, int speed, + unsigned char r, unsigned char g, unsigned char b, + int phase) { CharAnimations* ca = GetAnims(); if (!ca) return; - if (location >= 32) return; - if (location == -1) { + if (location == 0xff) { ca->GlobalColorMod.type = type; ca->GlobalColorMod.speed = speed; ca->GlobalColorMod.rgb.r = r; @@ -2318,15 +2317,18 @@ ca->GlobalColorMod.rgb.b = b; if (phase >= 0) ca->GlobalColorMod.phase = phase; - } else { - ca->ColorMods[location].type = type; - ca->ColorMods[location].speed = speed; - ca->ColorMods[location].rgb.r = r; - ca->ColorMods[location].rgb.g = g; - ca->ColorMods[location].rgb.b = b; - if (phase >= 0) - ca->ColorMods[location].phase = phase; + return; } + //00xx0yyy-->000xxyyy + if (location&0xc8) return; //invalid location + location = (location &7) | ((location>>1)&0x18); + ca->ColorMods[location].type = type; + ca->ColorMods[location].speed = speed; + ca->ColorMods[location].rgb.r = r; + ca->ColorMods[location].rgb.g = g; + ca->ColorMods[location].rgb.b = b; + if (phase >= 0) + ca->ColorMods[location].phase = phase; } void Actor::SetLeader(Actor *actor, int xoffset, int yoffset) Modified: gemrb/trunk/gemrb/plugins/Core/Actor.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-04-24 16:34:56 UTC (rev 4611) +++ gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-04-28 07:32:50 UTC (rev 4612) @@ -386,7 +386,7 @@ /* sets a colour gradient stat, handles location */ void SetColor( ieDword idx, ieDword grd); /* sets an RGB colour modification effect; location -1 for global */ - void SetColorMod( int location, RGBModifier::Type type, int speed, + void SetColorMod( ieByte location, RGBModifier::Type type, int speed, unsigned char r, unsigned char g, unsigned char b, int phase=-1 ); bool Schedule(ieDword gametime); Modified: gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-04-24 16:34:56 UTC (rev 4611) +++ gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-04-28 07:32:50 UTC (rev 4612) @@ -929,9 +929,9 @@ { if (0) printf( "fx_set_color_rgb (%2d): RGB: %x, Location: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - int location = (fx->Parameter2 & 0xF) + 8*((fx->Parameter2 & 0xF0)>>4); + ieByte location = fx->Parameter2 & 0xff; target->SetColorMod(location, RGBModifier::ADD, -1, fx->Parameter1 >> 8, - fx->Parameter1 >> 16, fx->Parameter1 >> 24); + fx->Parameter1 >> 16, fx->Parameter1 >> 24); return FX_APPLIED; } @@ -940,9 +940,8 @@ { if (0) printf( "fx_set_color_rgb_global (%2d): RGB: %x, Location: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - int location = -1; - target->SetColorMod(location, RGBModifier::ADD, -1, fx->Parameter1 >> 8, - fx->Parameter1 >> 16, fx->Parameter1 >> 24); + target->SetColorMod(0xff, RGBModifier::ADD, -1, fx->Parameter1 >> 8, + fx->Parameter1 >> 16, fx->Parameter1 >> 24); return FX_APPLIED; } @@ -952,11 +951,11 @@ { if (0) printf( "fx_set_color_pulse_rgb (%2d): RGB: %x, Location: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - int location = (fx->Parameter2 & 0xF) + 8*((fx->Parameter2 & 0xF0)>>4); + ieByte location = fx->Parameter2 & 0xff; int speed = (fx->Parameter2 >> 16) & 0xFF; target->SetColorMod(location, RGBModifier::ADD, speed, - fx->Parameter1 >> 8, fx->Parameter1 >> 16, - fx->Parameter1 >> 24); + fx->Parameter1 >> 8, fx->Parameter1 >> 16, + fx->Parameter1 >> 24); return FX_APPLIED; } @@ -967,9 +966,9 @@ if (0) printf( "fx_set_color_pulse_rgb_global (%2d): RGB: %x, Location: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); int speed = (fx->Parameter2 >> 16) & 0xFF; - target->SetColorMod(-1, RGBModifier::ADD, speed, - fx->Parameter1 >> 8, fx->Parameter1 >> 16, - fx->Parameter1 >> 24); + target->SetColorMod(0xff, RGBModifier::ADD, speed, + fx->Parameter1 >> 8, fx->Parameter1 >> 16, + fx->Parameter1 >> 24); return FX_APPLIED; } @@ -1624,9 +1623,9 @@ if (0) printf( "fx_brief_rgb (%2d): RGB: %d, Location and speed: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); int speed = (fx->Parameter2 >> 16) & 0xFF; - target->SetColorMod(-1, RGBModifier::ADD, speed, - fx->Parameter1 >> 8, fx->Parameter1 >> 16, - fx->Parameter1 >> 24, 0); + target->SetColorMod(0xff, RGBModifier::ADD, speed, + fx->Parameter1 >> 8, fx->Parameter1 >> 16, + fx->Parameter1 >> 24, 0); return FX_NOT_APPLIED; } @@ -1635,9 +1634,9 @@ { if (0) printf( "fx_darken_rgb (%2d): RGB: %d, Location and speed: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - int location = (fx->Parameter2 & 0xF) + 8*((fx->Parameter2 & 0xF0)>>4); + ieByte location = fx->Parameter2 & 0xff; target->SetColorMod(location, RGBModifier::TINT, -1, fx->Parameter1 >> 8, - fx->Parameter1 >> 16, fx->Parameter1 >> 24); + fx->Parameter1 >> 16, fx->Parameter1 >> 24); return FX_APPLIED; } // 0x34 Color:GlowRGB @@ -1645,10 +1644,10 @@ { if (0) printf( "fx_glow_rgb (%2d): RGB: %d, Location and speed: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - int location = (fx->Parameter2 & 0xF) + 8*((fx->Parameter2 & 0xF0)>>4); + ieByte location = fx->Parameter2 & 0xff; target->SetColorMod(location, RGBModifier::BRIGHTEN, -1, - fx->Parameter1 >> 8, fx->Parameter1 >> 16, - fx->Parameter1 >> 24); + fx->Parameter1 >> 8, fx->Parameter1 >> 16, + fx->Parameter1 >> 24); return FX_APPLIED; } Modified: gemrb/trunk/gemrb/plugins/IWDOpcodes/IWDOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/IWDOpcodes/IWDOpc.cpp 2007-04-24 16:34:56 UTC (rev 4611) +++ gemrb/trunk/gemrb/plugins/IWDOpcodes/IWDOpc.cpp 2007-04-28 07:32:50 UTC (rev 4612) @@ -344,9 +344,9 @@ if (0) printf( "fx_fade_rgb (%2d): \n", fx->Opcode ); int speed = (fx->Parameter2 >> 16) & 0xFF; - target->SetColorMod(-1, RGBModifier::ADD, speed, - fx->Parameter1 >> 8, fx->Parameter1 >> 16, - fx->Parameter1 >> 24, speed); + target->SetColorMod(0xff, RGBModifier::ADD, speed, + fx->Parameter1 >> 8, fx->Parameter1 >> 16, + fx->Parameter1 >> 24, speed); return FX_NOT_APPLIED; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-04-28 13:43:04
|
Revision: 4617 http://gemrb.svn.sourceforge.net/gemrb/?rev=4617&view=rev Author: avenger_teambg Date: 2007-04-28 06:42:42 -0700 (Sat, 28 Apr 2007) Log Message: ----------- implemented casting time implemented all spellcasting actions Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Actions.cpp gemrb/trunk/gemrb/plugins/Core/Actor.cpp gemrb/trunk/gemrb/plugins/Core/Actor.h gemrb/trunk/gemrb/plugins/Core/ActorBlock.cpp gemrb/trunk/gemrb/plugins/Core/ActorBlock.h gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp gemrb/trunk/gemrb/plugins/Core/GameControl.cpp gemrb/trunk/gemrb/plugins/Core/GameScript.cpp gemrb/trunk/gemrb/plugins/Core/GameScript.h gemrb/trunk/gemrb/plugins/Core/Interface.cpp gemrb/trunk/gemrb/plugins/Core/Item.h gemrb/trunk/gemrb/plugins/Core/Spell.cpp gemrb/trunk/gemrb/plugins/Core/Spell.h gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp Modified: gemrb/trunk/gemrb/plugins/Core/Actions.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-04-28 13:32:52 UTC (rev 4616) +++ gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-04-28 13:42:42 UTC (rev 4617) @@ -2071,91 +2071,109 @@ parameters->pointParameter, parameters->int0Parameter, true); } +//spell is depleted, casting time is calculated void GameScript::Spell(Scriptable* Sender, Action* parameters) { ieResRef spellres; -printf("Spell casting\n"); + //resolve spellname if (!ResolveSpellName( spellres, parameters) ) { -printf("failed to resolve\n"); Sender->ReleaseCurrentAction(); return; } + //if target was set, fire spell + if (Sender->LastTarget) { + Sender->CastSpellEnd( spellres ); + Sender->ReleaseCurrentAction(); + return; + } + + //parse target Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); if (!tar) { Sender->ReleaseCurrentAction(); return; } - if (Sender->Type == ST_ACTOR) { - Actor *actor = (Actor *) Sender; - actor->SetStance (IE_ANI_CAST); - actor->CastSpell (spellres, tar, true); + + //set target + Sender->CastSpell( spellres, tar, true ); + + //if target was set, feed action back + if (Sender->LastTarget) { + Sender->AddActionInFront( Sender->CurrentAction ); } - Point s,d; - GetPositionFromScriptable( Sender, s, false ); - GetPositionFromScriptable( tar, d, false ); -printf( "Spell from [%d,%d] to [%d,%d]\n", s.x, s.y, d.x, d.y ); - //this might be bad - Sender->ReleaseCurrentAction(); } +//spell is depleted, casting time is calculated void GameScript::SpellPoint(Scriptable* Sender, Action* parameters) { ieResRef spellres; -printf("Spell casting\n"); + //resolve spellname if (!ResolveSpellName( spellres, parameters) ) { -printf("failed to resolve\n"); Sender->ReleaseCurrentAction(); return; } + //if target was set, fire spell + if (!Sender->LastTargetPos.isempty()) { + Sender->CastSpellPointEnd( spellres ); + Sender->ReleaseCurrentAction(); + return; + } + + //parse target Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); if (!tar) { Sender->ReleaseCurrentAction(); return; } - if (Sender->Type == ST_ACTOR) { - Actor *actor = (Actor *) Sender; - actor->SetStance (IE_ANI_CAST); - actor->CastSpellPoint (spellres, parameters->pointParameter, true); + + //set target + Sender->CastSpellPoint( spellres, parameters->pointParameter, true ); + + //if target was set, feed action back + if (!Sender->LastTargetPos.isempty()) { + Sender->AddActionInFront( Sender->CurrentAction ); } - Point s; - GetPositionFromScriptable( Sender, s, false ); - printf( "Spell from [%d,%d] to [%d,%d]\n", s.x, s.y, parameters->pointParameter.x, parameters->pointParameter.y ); - //this might be bad - Sender->ReleaseCurrentAction(); } -//it is unsure how the ForceSpell actions differ +//spell isn't depleted, but casting time is calculated void GameScript::ForceSpell(Scriptable* Sender, Action* parameters) { ieResRef spellres; + //resolve spellname if (!ResolveSpellName( spellres, parameters) ) { Sender->ReleaseCurrentAction(); return; } + //if target was set, fire spell + if (!Sender->LastTarget) { + Sender->CastSpellEnd( spellres ); + Sender->ReleaseCurrentAction(); + return; + } + + //parse target Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); if (!tar) { Sender->ReleaseCurrentAction(); return; } - if (Sender->Type == ST_ACTOR) { - Actor *actor = (Actor *) Sender; - actor->SetStance (IE_ANI_CAST); - actor->CastSpell (spellres, tar, false); + + //set target + Sender->CastSpell (spellres, tar, false); + + //if target was set, feed action back + if (Sender->LastTarget) { + Sender->AddActionInFront( Sender->CurrentAction ); } - Point s,d; - GetPositionFromScriptable( Sender, s, false ); - GetPositionFromScriptable( tar, d, false ); - printf( "ForceSpell from [%d,%d] to [%d,%d]\n", s.x, s.y, d.x, d.y ); - //this might be bad - Sender->ReleaseCurrentAction(); } +//spell isn't depleted, but casting time is calculated void GameScript::ForceSpellPoint(Scriptable* Sender, Action* parameters) { ieResRef spellres; @@ -2165,23 +2183,30 @@ return; } + //if target was set, fire spell + if (!Sender->LastTargetPos.isempty()) { + Sender->CastSpellPointEnd( spellres ); + Sender->ReleaseCurrentAction(); + return; + } + + //parse target Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); if (!tar) { Sender->ReleaseCurrentAction(); return; } - if (Sender->Type == ST_ACTOR) { - Actor *actor = (Actor *) Sender; - actor->SetStance (IE_ANI_CAST); - actor->CastSpellPoint (spellres, parameters->pointParameter, false); + + //set target + Sender->CastSpellPoint (spellres, parameters->pointParameter, false); + + //if target was set, feed action back + if (!Sender->LastTargetPos.isempty()) { + Sender->AddActionInFront( Sender->CurrentAction ); } - Point s; - GetPositionFromScriptable( Sender, s, false ); - printf( "ForceSpell from [%d,%d] to [%d,%d]\n", s.x, s.y, parameters->pointParameter.x, parameters->pointParameter.y ); - //this might be bad - Sender->ReleaseCurrentAction(); } +//zero casting time, no depletion void GameScript::ReallyForceSpell(Scriptable* Sender, Action* parameters) { ieResRef spellres; @@ -2196,25 +2221,42 @@ Sender->ReleaseCurrentAction(); return; } - Actor *actor = NULL; - if (Sender->Type == ST_ACTOR) { - actor = (Actor *) Sender; - actor->SetStance (IE_ANI_CAST); - } - Point s,d; - GetPositionFromScriptable( Sender, s, false ); - GetPositionFromScriptable( tar, d, false ); - printf( "ReallyForceSpell from [%d,%d] to [%d,%d]\n", s.x, s.y, d.x, d.y ); - //temporarily if (tar->Type==ST_ACTOR) { - core->ApplySpell(spellres, (Actor *) tar, actor, 0); + Sender->LastTarget=tar->GetGlobalID(); } else { - core->ApplySpellPoint(spellres, tar, tar->Pos, actor, 0); + GetPositionFromScriptable(tar, Sender->LastTargetPos, false); } + Sender->CastSpellPointEnd(spellres); Sender->ReleaseCurrentAction(); } +//zero casting time, no depletion (finish casting at point) +//no CFB +void GameScript::ReallyForceSpellPoint(Scriptable* Sender, Action* parameters) +{ + ieResRef spellres; + + if (!ResolveSpellName( spellres, parameters) ) { + Sender->ReleaseCurrentAction(); + return; + } + + Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); + if (!tar) { + Sender->ReleaseCurrentAction(); + return; + } + Sender->LastTargetPos=parameters->pointParameter; + if (Sender->Type == ST_ACTOR) { + Actor *actor = (Actor *) Sender; + actor->SetStance (IE_ANI_CONJURE); + } + Sender->CastSpellPointEnd(spellres); + Sender->ReleaseCurrentAction(); +} + // this differs from ReallyForceSpell that this one allows dead Sender casting +// zero casting time, no depletion void GameScript::ReallyForceSpellDead(Scriptable* Sender, Action* parameters) { ieResRef spellres; @@ -2229,21 +2271,12 @@ Sender->ReleaseCurrentAction(); return; } - Actor *actor = NULL; + Sender->LastTargetPos=parameters->pointParameter; if (Sender->Type == ST_ACTOR) { - actor = (Actor *) Sender; + Actor *actor = (Actor *) Sender; + actor->SetStance (IE_ANI_CONJURE); } - Point s,d; - GetPositionFromScriptable( Sender, s, false ); - GetPositionFromScriptable( tar, d, false ); - printf( "ReallyForceSpellDead from [%d,%d] to [%d,%d]\n", s.x, s.y, d.x, d.y ); - //this might be bad - //temporarily - if (tar->Type==ST_ACTOR) { - core->ApplySpell(spellres, (Actor *) tar, actor, 0); - } else { - core->ApplySpellPoint(spellres, tar, tar->Pos, actor, 0); - } + Sender->CastSpellPointEnd(spellres); Sender->ReleaseCurrentAction(); } @@ -2640,9 +2673,8 @@ Actor* actor = ( Actor* ) Sender; actor->SetStance( IE_ANI_DIE ); actor->NoInterrupt(); - //actor->InternalFlags|=IF_NOINT; actor->playDeadCounter = parameters->int0Parameter; - actor->SetWait( parameters->int0Parameter ); + actor->SetWait( 1 ); } /** no difference at this moment, but this action should be interruptable */ @@ -2657,7 +2689,7 @@ actor->SetStance( IE_ANI_DIE ); //also set time for playdead! actor->playDeadCounter = parameters->int0Parameter; - actor->SetWait( parameters->int0Parameter ); + actor->SetWait( 1 ); } /* this may not be correct, just a placeholder you can fix */ @@ -4253,10 +4285,12 @@ } Actor *actor = (Actor *) Sender; if (parameters->string0Parameter[0]) { - actor->spellbook.HaveSpell(parameters->string0Parameter, HS_DEPLETE); + //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); } void GameScript::SetScriptName( Scriptable* Sender, Action* parameters) @@ -4903,7 +4937,9 @@ owner = NULL; } //apply spell on point - core->ApplySpellPoint(spellres, tar, tar->Pos, owner, parameters->int1Parameter); + Point d; + GetPositionFromScriptable(tar, d, false); + core->ApplySpellPoint(spellres, tar->GetCurrentArea(), d, owner, parameters->int1Parameter); } } @@ -4921,8 +4957,7 @@ } else { owner = NULL; } - Scriptable *tar = Sender->GetCurrentArea(); - core->ApplySpellPoint(spellres, tar, parameters->pointParameter, owner, parameters->int1Parameter); + core->ApplySpellPoint(spellres, Sender->GetCurrentArea(), parameters->pointParameter, owner, parameters->int1Parameter); } //this is a gemrb extension @@ -5361,8 +5396,7 @@ Actor *scr = (Actor *)Sender; Actor *actor = (Actor *)tar; scr->LastFollowed = actor->GetID(); - scr->FollowOffset.x = -1; - scr->FollowOffset.y = -1; + scr->FollowOffset.empty(); } void GameScript::RunFollow(Scriptable* Sender, Action* parameters) @@ -5378,8 +5412,7 @@ Actor *scr = (Actor *)Sender; Actor *actor = (Actor *)tar; scr->LastFollowed = actor->GetID(); - scr->FollowOffset.x = -1; - scr->FollowOffset.y = -1; + scr->FollowOffset.empty(); scr->WalkTo(actor->Pos, IF_RUNNING, 1); Sender->ReleaseCurrentAction(); } Modified: gemrb/trunk/gemrb/plugins/Core/Actor.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-04-28 13:32:52 UTC (rev 4616) +++ gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-04-28 13:42:42 UTC (rev 4617) @@ -1315,6 +1315,18 @@ DisplayStringCore(this, VB_DAMAGE, DS_CONSOLE|DS_CONST ); } +bool Actor::HandleCastingStance(ieResRef SpellResRef, bool deplete) +{ + if (deplete) { + if (! spellbook.HaveSpell( SpellResRef, HS_DEPLETE )) { + SetStance(IE_ANI_READY); + return true; + } + } + SetStance(IE_ANI_CAST); + return false; +} + //returns actual damage int Actor::Damage(int damage, int damagetype, Actor *hitter) { @@ -2302,7 +2314,7 @@ */ } -void Actor::SetColorMod( ieByte location, RGBModifier::Type type, int speed, +void Actor::SetColorMod( ieDword location, RGBModifier::Type type, int speed, unsigned char r, unsigned char g, unsigned char b, int phase) { @@ -2317,10 +2329,14 @@ ca->GlobalColorMod.rgb.b = b; if (phase >= 0) ca->GlobalColorMod.phase = phase; + else { + if (ca->GlobalColorMod.phase > 2*speed) + ca->GlobalColorMod.phase=0; + } return; } //00xx0yyy-->000xxyyy - if (location&0xc8) return; //invalid location + if (location&0xffffffc8) return; //invalid location location = (location &7) | ((location>>1)&0x18); ca->ColorMods[location].type = type; ca->ColorMods[location].speed = speed; @@ -2329,6 +2345,10 @@ ca->ColorMods[location].rgb.b = b; if (phase >= 0) ca->ColorMods[location].phase = phase; + else { + if (ca->ColorMods[location].phase > 2*speed) + ca->ColorMods[location].phase = 0; + } } void Actor::SetLeader(Actor *actor, int xoffset, int yoffset) @@ -3066,6 +3086,7 @@ if ((header<CHARGE_COUNTERS) && !item->Usages[header]) { return false; } + Projectile *pro = itm->GetProjectile(header); ChargeItem(slot, header, item, itm, silent); core->FreeItem(itm,item->ItemResRef, false); @@ -3102,63 +3123,6 @@ } } -bool Actor::CastSpellPoint( ieResRef SpellResRef, Point &target, bool deplete ) -{ - if (deplete) { - if (! spellbook.HaveSpell( SpellResRef, HS_DEPLETE )) { - SetStance(IE_ANI_READY); - return false; - } - } - - SetStance(IE_ANI_CONJURE); - Spell* spl = core->GetSpell( SpellResRef ); - //cfb - int dummy; - EffectQueue *fxqueue=spl->GetEffectBlock(-1, dummy); - fxqueue->SetOwner(this); - fxqueue->ApplyAllEffects(this); - //spell - Projectile *pro=spl->GetProjectile(GetXPLevel(true)); - if (pro) { - pro->SetCaster(globalID); - GetCurrentArea()->AddProjectile(pro, Pos, target); - return true; - } - return false; -} - -bool Actor::CastSpell( ieResRef SpellResRef, Scriptable* target, bool deplete ) -{ - if (target->Type!=ST_ACTOR) { - return CastSpellPoint(SpellResRef, target->Pos, deplete); - } - - if (deplete) { - if (! spellbook.HaveSpell( SpellResRef, HS_DEPLETE )) { - SetStance(IE_ANI_READY); - return false; - } - } - - SetStance(IE_ANI_CONJURE); - Actor *Target = (Actor *) target; - Spell* spl = core->GetSpell( SpellResRef ); - //cfb - int dummy; - EffectQueue *fxqueue=spl->GetEffectBlock(-1, dummy); - fxqueue->SetOwner(this); - fxqueue->ApplyAllEffects(this); - //spell - Projectile *pro=spl->GetProjectile(GetXPLevel(true)); - if (pro) { - pro->SetCaster(globalID); - GetCurrentArea()->AddProjectile(pro, Pos, Target->globalID); - return true; - } - return false; -} - bool Actor::IsReverseToHit() { return REVERSE_TOHIT; Modified: gemrb/trunk/gemrb/plugins/Core/Actor.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-04-28 13:32:52 UTC (rev 4616) +++ gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-04-28 13:42:42 UTC (rev 4617) @@ -319,6 +319,8 @@ void DialogInterrupt(); /* called when actor was hit */ void GetHit(); + /* called when actor starts to cast a spell*/ + bool HandleCastingStance(ieResRef SpellResRef, bool deplete); /* deals damage to this actor */ int Damage(int damage, int damagetype, Actor *hitter); /* drops items from inventory to current spot */ @@ -361,7 +363,7 @@ /* returns the ranged weapon header associated with the currently equipped projectile */ int GetRangedWeapon(ITMExtHeader *&which); /* Returns current weapon range and extended header - if range is nonzero, then which is valid */ + if range is nonzero, then which is valid */ unsigned int GetWeapon(ITMExtHeader *&which, bool leftorright=false); /* Creates player statistics */ void CreateStats(); @@ -385,8 +387,8 @@ void DealDamage(Actor *target, int damage,int damagetype, bool critical); /* sets a colour gradient stat, handles location */ void SetColor( ieDword idx, ieDword grd); - /* sets an RGB colour modification effect; location -1 for global */ - void SetColorMod( ieByte location, RGBModifier::Type type, int speed, + /* sets an RGB colour modification effect; location 0xff for global */ + void SetColorMod( ieDword location, RGBModifier::Type type, int speed, unsigned char r, unsigned char g, unsigned char b, int phase=-1 ); bool Schedule(ieDword gametime); @@ -437,9 +439,6 @@ bool UseItem(int slot, ieDword header, Scriptable *target, bool silent); /* Deducts a charge from an item */ void ChargeItem(int slot, ieDword header, CREItem *item, Item *itm, bool silent); - /* actor casts spell */ - bool CastSpellPoint( ieResRef SpellResRef, Point &Target, bool deplete ); - bool CastSpell( ieResRef SpellResRef, Scriptable* Target, bool deplete ); /* If it returns true, then default AC=10 and the lesser the better */ bool IsReverseToHit(); void InitButtons(ieDword cls); Modified: gemrb/trunk/gemrb/plugins/Core/ActorBlock.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/ActorBlock.cpp 2007-04-28 13:32:52 UTC (rev 4616) +++ gemrb/trunk/gemrb/plugins/Core/ActorBlock.cpp 2007-04-28 13:42:42 UTC (rev 4617) @@ -25,9 +25,11 @@ #include "Video.h" #include "SoundMgr.h" #include "Item.h" +#include "Spell.h" #include "Map.h" #include "Game.h" #include "GameControl.h" +#include "Projectile.h" #include <cassert> @@ -72,6 +74,8 @@ Pos.y = 0; scriptName[0] = 0; + SpellHeader = -1; + LastTargetPos.empty(); locals = new Variables(); locals->SetType( GEM_VARIABLES_INT ); locals->ParseKey( 1 ); @@ -301,6 +305,15 @@ } } +ieWord Scriptable::GetGlobalID() +{ + if (Type == ST_ACTOR) { + Actor *actor = (Actor *) this; + return actor->globalID; + } + return 0; +} + void Scriptable::ProcessActions(bool force) { unsigned long thisTime = core->GetGame()->Ticks; @@ -493,6 +506,122 @@ tolist.push_back(actorref); } +void Scriptable::CastSpellPointEnd( ieResRef SpellResRef ) +{ + if (Type==ST_ACTOR) { + ((Actor *) this)->SetStance(IE_ANI_CONJURE); + } + + if (SpellHeader == -1) { + LastTargetPos.empty(); + return; + } + + if (LastTargetPos.isempty()) { + SpellHeader = -1; + return; + } + + Spell* spl = core->GetSpell( SpellResRef ); + //create projectile from known spellheader + Projectile *pro=spl->GetProjectile(SpellHeader); + SpellHeader = -1; + if (pro) { + pro->SetCaster(GetGlobalID()); + GetCurrentArea()->AddProjectile(pro, Pos, LastTargetPos); + } +} + +void Scriptable::CastSpellEnd( ieResRef SpellResRef ) +{ + if (Type==ST_ACTOR) { + ((Actor *) this)->SetStance(IE_ANI_CONJURE); + } + + if (SpellHeader == -1) { + LastTarget=0; + return; + } + if (!LastTarget) { + SpellHeader = -1; + return; + } + Spell* spl = core->GetSpell( SpellResRef ); + //create projectile from known spellheader + Projectile *pro=spl->GetProjectile(SpellHeader); + if (pro) { + pro->SetCaster(GetGlobalID()); + GetCurrentArea()->AddProjectile(pro, Pos, LastTarget); + } + core->FreeSpell(spl, SpellResRef, false); +} + +//set target as point +//if spell needs to be depleted, do it +//if spell is illegal stop casting +void Scriptable::CastSpellPoint( ieResRef SpellResRef, Point &target, bool deplete ) +{ + LastTarget = 0; + LastTargetPos.empty(); + if (Type==ST_ACTOR) { + Actor *actor = (Actor *) this; + if (actor->HandleCastingStance(SpellResRef,deplete) ) { + return; + } + } + LastTarget = 0; + LastTargetPos = target; + SpellCast(SpellResRef); +} + +//set target as actor (if target isn't actor, use its position) +//if spell needs to be depleted, do it +//if spell is illegal stop casting +void Scriptable::CastSpell( ieResRef SpellResRef, Scriptable* target, bool deplete ) +{ + LastTarget = 0; + LastTargetPos.empty(); + if (Type==ST_ACTOR) { + Actor *actor = (Actor *) this; + if (actor->HandleCastingStance(SpellResRef,deplete) ) { + return; + } + } + + if (target->Type!=ST_ACTOR) { + LastTargetPos = target->Pos; + } else { + LastTarget = target->GetGlobalID(); + } + SpellCast(SpellResRef); +} + +//start spellcasting (common part) +void Scriptable::SpellCast(ieResRef SpellResRef) +{ + Spell* spl = core->GetSpell( SpellResRef ); + if (!spl) { + SpellHeader = -1; + return; + } + + //cfb + int level = 0; + if (Type==ST_ACTOR) { + Actor *actor = (Actor *) this; + EffectQueue *fxqueue=spl->GetEffectBlock(-1); + fxqueue->SetOwner(actor); + fxqueue->ApplyAllEffects(actor); + delete fxqueue; + level = ((Actor *) this)->GetXPLevel(true); + } + + SpellHeader = spl->GetHeaderIndexFromLevel(level); + SPLExtHeader *header = spl->GetExtHeader(SpellHeader); + SetWait(header->CastingTime*AI_UPDATE_TIME); + core->FreeSpell(spl, SpellResRef, false); +} + /******************** * Selectable Class * ********************/ @@ -720,6 +849,13 @@ void Movable::SetStance(unsigned int arg) { + if (StanceID==IE_ANI_DIE) { + if (GetInternalFlag()&IF_REALLYDIED) { + printMessage("Movable","Stance overridden by death\n", YELLOW); + return; + } + } + if (arg<MAX_ANIMS) { StanceID=(unsigned char) arg; @@ -1250,8 +1386,7 @@ TrapDetectionDiff = 0; TrapRemovalDiff = 0; TrapDetected = 0; - TrapLaunch.x = 0; - TrapLaunch.y = 0; + TrapLaunch.empty(); Dialog[0] = 0; } Modified: gemrb/trunk/gemrb/plugins/Core/ActorBlock.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/ActorBlock.h 2007-04-28 13:32:52 UTC (rev 4616) +++ gemrb/trunk/gemrb/plugins/Core/ActorBlock.h 2007-04-28 13:42:42 UTC (rev 4617) @@ -188,13 +188,15 @@ ieDword LastTrigger; // also LastClosed ieDword LastEntered; // also LastOpened ieDword LastDisarmed; // also LastAttacker - ieDword LastDisarmFailed; + ieDword LastDisarmFailed; //also LastTarget ieDword LastUnlocked; ieDword LastOpenFailed; // also LastPickpocketFailed ieDword LastPickLockFailed; std::list< Action*> actionQueue; Action* CurrentAction; unsigned long playDeadCounter; + Point LastTargetPos; + int SpellHeader; public: /** Gets the Dialog ResRef */ const char* GetDialog(void) const @@ -243,6 +245,16 @@ void AddTrigger(ieDword *actorref); /* re/draws overhead text on the map screen */ void DrawOverheadText(Region &screen); + /* actor/scriptable casts spell */ + void CastSpellPoint( ieResRef SpellResRef, Point &Target, bool deplete ); + void CastSpell( ieResRef SpellResRef, Scriptable* Target, bool deplete ); + /* spellcasting finished */ + void CastSpellPointEnd( ieResRef SpellResRef); + void CastSpellEnd( ieResRef SpellResRef); + ieWord GetGlobalID(); +private: + /* used internally to handle start of spellcasting */ + void SpellCast(ieResRef SpellResRef); }; class GEM_EXPORT Selectable : public Scriptable { Modified: gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp 2007-04-28 13:32:52 UTC (rev 4616) +++ gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp 2007-04-28 13:42:42 UTC (rev 4617) @@ -462,6 +462,7 @@ flg = false; break; } + return flg; } Modified: gemrb/trunk/gemrb/plugins/Core/GameControl.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameControl.cpp 2007-04-28 13:32:52 UTC (rev 4616) +++ gemrb/trunk/gemrb/plugins/Core/GameControl.cpp 2007-04-28 13:42:42 UTC (rev 4617) @@ -99,8 +99,7 @@ overContainer = NULL; overInfoPoint = NULL; drawPath = NULL; - pfs.x = 0; - pfs.y = 0; + pfs.null(); lastCursor = IE_CURSOR_NORMAL; moveX = moveY = 0; DebugFlags = 0; @@ -590,8 +589,7 @@ case 'c': if (game->selected.size() > 0 && lastActor) { Actor *src = game->selected[0]; - bool res = src->CastSpell( "SPWI207", lastActor, false ); - printf( "Cast Spell: %d\n", res ); + src->CastSpell( "SPWI207", lastActor, false ); } break; Modified: gemrb/trunk/gemrb/plugins/Core/GameScript.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameScript.cpp 2007-04-28 13:32:52 UTC (rev 4616) +++ gemrb/trunk/gemrb/plugins/Core/GameScript.cpp 2007-04-28 13:42:42 UTC (rev 4617) @@ -119,9 +119,9 @@ {"glt", GameScript::GLT_Trigger, 0}, {"global", GameScript::Global,TF_MERGESTRINGS}, {"globalandglobal", GameScript::GlobalAndGlobal_Trigger,TF_MERGESTRINGS}, - {"globalband", GameScript::BitCheck,AF_MERGESTRINGS}, - {"globalbandglobal", GameScript::GlobalBAndGlobal_Trigger,AF_MERGESTRINGS}, - {"globalbandglobalexact", GameScript::GlobalBAndGlobalExact,AF_MERGESTRINGS}, + {"globalband", GameScript::BitCheck,TF_MERGESTRINGS}, + {"globalbandglobal", GameScript::GlobalBAndGlobal_Trigger,TF_MERGESTRINGS}, + {"globalbandglobalexact", GameScript::GlobalBAndGlobalExact,TF_MERGESTRINGS}, {"globalbitglobal", GameScript::GlobalBitGlobal_Trigger,TF_MERGESTRINGS}, {"globalequalsglobal", GameScript::GlobalsEqual,TF_MERGESTRINGS}, //this is the same {"globalgt", GameScript::GlobalGT,TF_MERGESTRINGS}, @@ -394,14 +394,14 @@ {"applyspell", GameScript::ApplySpell, 0}, {"applyspellpoint", GameScript::ApplySpellPoint, 0}, //gemrb extension {"attachtransitiontodoor", GameScript::AttachTransitionToDoor, 0}, - {"attack", GameScript::Attack,AF_BLOCKING}, - {"attacknosound", GameScript::AttackNoSound,AF_BLOCKING}, //no sound yet anyway - {"attackoneround", GameScript::AttackOneRound,AF_BLOCKING}, - {"attackreevaluate", GameScript::AttackReevaluate,AF_BLOCKING}, - {"backstab", GameScript::Attack,AF_BLOCKING},//actually hide+attack - {"bashdoor", GameScript::BashDoor,AF_BLOCKING}, //the same until we know better - {"battlesong", GameScript::BattleSong, 0}, - {"berserk", GameScript::Berserk, 0}, + {"attack", GameScript::Attack,AF_BLOCKING|AF_ALIVE}, + {"attacknosound", GameScript::AttackNoSound,AF_BLOCKING|AF_ALIVE}, //no sound yet anyway + {"attackoneround", GameScript::AttackOneRound,AF_BLOCKING|AF_ALIVE}, + {"attackreevaluate", GameScript::AttackReevaluate,AF_BLOCKING|AF_ALIVE}, + {"backstab", GameScript::Attack,AF_BLOCKING|AF_ALIVE},//actually hide+attack + {"bashdoor", GameScript::BashDoor,AF_BLOCKING|AF_ALIVE}, //the same until we know better + {"battlesong", GameScript::BattleSong, AF_ALIVE}, + {"berserk", GameScript::Berserk, AF_ALIVE}, {"bitclear", GameScript::BitClear,AF_MERGESTRINGS}, {"bitglobal", GameScript::BitGlobal,AF_MERGESTRINGS}, {"bitset", GameScript::GlobalBOr,AF_MERGESTRINGS}, //probably the same @@ -537,9 +537,9 @@ {"floatmessagefixedrnd", GameScript::FloatMessageFixedRnd, 0}, {"floatmessagernd", GameScript::FloatMessageRnd, 0}, {"floatrebus", GameScript::FloatRebus, 0}, - {"follow", GameScript::Follow, 0}, - {"followcreature", GameScript::FollowCreature, AF_BLOCKING}, //pst - {"followobjectformation", GameScript::FollowObjectFormation, AF_BLOCKING}, + {"follow", GameScript::Follow, AF_ALIVE}, + {"followcreature", GameScript::FollowCreature, AF_BLOCKING|AF_ALIVE}, //pst + {"followobjectformation", GameScript::FollowObjectFormation, AF_BLOCKING|AF_ALIVE}, {"forceaiscript", GameScript::ForceAIScript, 0}, {"forceattack", GameScript::ForceAttack, 0}, {"forcefacing", GameScript::ForceFacing, 0}, @@ -646,12 +646,12 @@ {"moveviewobject", GameScript::MoveViewObject, AF_BLOCKING}, {"moveviewpoint", GameScript::MoveViewPoint, AF_BLOCKING}, {"moveviewpointuntildone", GameScript::MoveViewPoint, 0}, - {"nidspecial1", GameScript::NIDSpecial1,AF_BLOCKING|AF_DIRECT},//we use this for dialogs, hack + {"nidspecial1", GameScript::NIDSpecial1,AF_BLOCKING|AF_DIRECT|AF_ALIVE},//we use this for dialogs, hack {"nidspecial2", GameScript::NIDSpecial2,AF_BLOCKING},//we use this for worldmap, another hack - {"nidspecial3", GameScript::Attack,AF_BLOCKING|AF_DIRECT},//this hack is for attacking preset target - {"nidspecial4", GameScript::ProtectObject,AF_BLOCKING|AF_DIRECT}, - {"nidspecial5", GameScript::UseItem, AF_BLOCKING|AF_DIRECT}, - {"nidspecial6", GameScript::Spell, AF_BLOCKING|AF_DIRECT}, + {"nidspecial3", GameScript::Attack,AF_BLOCKING|AF_DIRECT|AF_ALIVE},//this hack is for attacking preset target + {"nidspecial4", GameScript::ProtectObject,AF_BLOCKING|AF_DIRECT|AF_ALIVE}, + {"nidspecial5", GameScript::UseItem, AF_BLOCKING|AF_DIRECT|AF_ALIVE}, + {"nidspecial6", GameScript::Spell, AF_BLOCKING|AF_DIRECT|AF_ALIVE}, {"noaction", GameScript::NoAction, 0}, {"opendoor", GameScript::OpenDoor,AF_BLOCKING}, {"panic", GameScript::Panic, 0}, @@ -794,9 +794,9 @@ {"spawnptactivate", GameScript::SpawnPtActivate, 0}, {"spawnptdeactivate", GameScript::SpawnPtDeactivate, 0}, {"spawnptspawn", GameScript::SpawnPtSpawn, 0}, - {"spell", GameScript::Spell, AF_BLOCKING}, + {"spell", GameScript::Spell, AF_BLOCKING|AF_ALIVE}, {"spellhiteffectsprite", GameScript::SpellHitEffectSprite, 0}, - {"spellpoint", GameScript::SpellPoint, AF_BLOCKING}, + {"spellpoint", GameScript::SpellPoint, AF_BLOCKING|AF_ALIVE}, {"startcutscene", GameScript::StartCutScene, 0}, {"startcutsceneex", GameScript::StartCutScene, 0}, //pst (unknown) {"startcutscenemode", GameScript::StartCutSceneMode, 0}, @@ -3011,6 +3011,13 @@ //uninterruptable actions will set it back if (Sender->Type==ST_ACTOR) { Sender->Activate(); + if (actionflags[actionID]&AF_ALIVE) { + if (Sender->GetInternalFlag()&IF_STOPATTACK) { + printMessage("GameScript", "Aborted action due to death", YELLOW); + Sender->ReleaseCurrentAction(); + return; + } + } } func( Sender, aC ); } else { Modified: gemrb/trunk/gemrb/plugins/Core/GameScript.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameScript.h 2007-04-28 13:32:52 UTC (rev 4616) +++ gemrb/trunk/gemrb/plugins/Core/GameScript.h 2007-04-28 13:42:42 UTC (rev 4617) @@ -189,8 +189,7 @@ string1Parameter[0] = 0; int0Parameter = 0; int1Parameter = 0; - pointParameter.x = 0; - pointParameter.y = 0; + pointParameter.null(); canary = (unsigned long) 0xdeadbeef; }; ~Trigger() @@ -283,8 +282,7 @@ string0Parameter[0] = 0; string1Parameter[0] = 0; int0Parameter = 0; - pointParameter.x = 0; - pointParameter.y = 0; + pointParameter.null(); int1Parameter = 0; int2Parameter = 0; //changed now @@ -574,7 +572,7 @@ #define AF_SCRIPTLEVEL 64 //this hack will transfer scriptlevel to int0parameter at runtime (changecurrentscript relies on it) #define AF_INVALID 128 #define AF_DIRECT 256 //this hack will transfer target from gamecontrol to object1 at compile time - +#define AF_ALIVE 512 //only alive actors can do this struct ActionLink { const char* Name; ActionFunction Function; @@ -1225,6 +1223,7 @@ static void RealSetGlobalTimer(Scriptable* Sender, Action* parameters); static void ReallyForceSpell(Scriptable* Sender, Action* parameters); static void ReallyForceSpellDead(Scriptable* Sender, Action* parameters); + static void ReallyForceSpellPoint(Scriptable* Sender, Action* parameters); static void Recoil(Scriptable* Sender, Action* parameters); static void RegainPaladinHood(Scriptable* Sender, Action* parameters); static void RegainRangerHood(Scriptable* Sender, Action* parameters); Modified: gemrb/trunk/gemrb/plugins/Core/Interface.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Interface.cpp 2007-04-28 13:32:52 UTC (rev 4616) +++ gemrb/trunk/gemrb/plugins/Core/Interface.cpp 2007-04-28 13:42:42 UTC (rev 4617) @@ -4862,11 +4862,8 @@ actor->RollSaves(); - if (!level) { - level = 1; - } - int dummy; //the extended header # - EffectQueue *fxqueue = spell->GetEffectBlock(level, dummy); + level = spell->GetHeaderIndexFromLevel(level); + EffectQueue *fxqueue = spell->GetEffectBlock(level); //check effect immunities int res = fxqueue->CheckImmunity ( actor ); @@ -4880,17 +4877,14 @@ delete fxqueue; } -void Interface::ApplySpellPoint(const ieResRef resname, Scriptable* /*target*/, Point &/*pos*/, Actor *caster, int level) +void Interface::ApplySpellPoint(const ieResRef resname, Scriptable* /*area*/, Point &/*pos*/, Actor *caster, int level) { Spell *spell = GetSpell(resname); if (!spell) { return; } - if (!level) { - level = 1; - } - int dummy; - EffectQueue *fxqueue = spell->GetEffectBlock(level, dummy); + level = spell->GetHeaderIndexFromLevel(level); + EffectQueue *fxqueue = spell->GetEffectBlock(level); fxqueue->SetOwner( caster ); //add effect to area??? delete fxqueue; Modified: gemrb/trunk/gemrb/plugins/Core/Item.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Item.h 2007-04-28 13:32:52 UTC (rev 4616) +++ gemrb/trunk/gemrb/plugins/Core/Item.h 2007-04-28 13:42:42 UTC (rev 4617) @@ -240,7 +240,7 @@ } //-1 will return the equipping feature block - EffectQueue *GetEffectBlock(int usage) const; + EffectQueue *GetEffectBlock(int header) const; //returns a projectile created from an extended header Projectile *GetProjectile(int header) const; //Builds an equipping glow effect from gradient colour Modified: gemrb/trunk/gemrb/plugins/Core/Spell.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spell.cpp 2007-04-28 13:32:52 UTC (rev 4616) +++ gemrb/trunk/gemrb/plugins/Core/Spell.cpp 2007-04-28 13:42:42 UTC (rev 4617) @@ -44,26 +44,35 @@ core->FreeSPLExt(ext_headers, casting_features); } +int Spell::GetHeaderIndexFromLevel(int level) const +{ + if (level<0) return -1; + if (Flags & SF_SIMPLIFIED_DURATION) { + return level; + } + int block_index; + for(block_index=0;block_index<ExtHeaderCount-1;block_index++) { + if (ext_headers[block_index+1].RequiredLevel>level) { + return block_index; + } + } + return ExtHeaderCount-1; +} + //-1 will return cfb //0 will always return first spell block //otherwise set to caster level -EffectQueue *Spell::GetEffectBlock(int level, int &block_index) const +EffectQueue *Spell::GetEffectBlock(int block_index) const { Effect *features; int count; - - block_index=0; + //iwd2 has this hack - if (level>=0) { + if (block_index>=0) { if (Flags & SF_SIMPLIFIED_DURATION) { features = ext_headers[0].features; count = ext_headers[0].FeatureCount; } else { - 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; } @@ -79,7 +88,7 @@ //fxqueue->AddEffect will copy the effect, //so we don't risk any overwriting if (EffectQueue::HasDuration(features+i)) { - features[i].Duration=(TimePerLevel*level+TimeConstant)*7; + features[i].Duration=(TimePerLevel*block_index+TimeConstant)*7; } } fxqueue->AddEffect( features+i ); @@ -87,15 +96,14 @@ return fxqueue; } -Projectile *Spell::GetProjectile(int level) const +Projectile *Spell::GetProjectile(int header) const { - int ext_block; - EffectQueue *fx = GetEffectBlock(level, ext_block); - if (fx->GetEffectsCount()) { - Projectile *pro = core->GetProjectileServer()->GetProjectileByIndex(ext_headers[ext_block].ProjectileAnimation); - pro->SetEffects(fx); + SPLExtHeader *seh = GetExtHeader(header); + if (seh->FeatureCount) { + Projectile *pro = core->GetProjectileServer()->GetProjectileByIndex(seh->ProjectileAnimation); + + pro->SetEffects(GetEffectBlock(header)); return pro; } return NULL; } - Modified: gemrb/trunk/gemrb/plugins/Core/Spell.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spell.h 2007-04-28 13:32:52 UTC (rev 4616) +++ gemrb/trunk/gemrb/plugins/Core/Spell.h 2007-04-28 13:42:42 UTC (rev 4617) @@ -146,17 +146,19 @@ public: //returns the requested extended header - SPLExtHeader *GetExtHeader(unsigned int which) const + inline SPLExtHeader *GetExtHeader(unsigned int which) const { if(ExtHeaderCount<=which) { return NULL; } return ext_headers+which; } + //converts a wanted level to block index count + int GetHeaderIndexFromLevel(int level) const; //-1 will return the cfb - EffectQueue *GetEffectBlock(int wanted_level, int &block_index) const; + EffectQueue *GetEffectBlock(int block_index) const; //returns a projectile created from an extended header - Projectile *GetProjectile(int wanted_level) const; + Projectile *GetProjectile(int headerindex) const; }; #endif // ! SPELL_H Modified: gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-04-28 13:32:52 UTC (rev 4616) +++ gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-04-28 13:42:42 UTC (rev 4617) @@ -929,7 +929,7 @@ { if (0) printf( "fx_set_color_rgb (%2d): RGB: %x, Location: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - ieByte location = fx->Parameter2 & 0xff; + ieDword location = fx->Parameter2 & 0xff; target->SetColorMod(location, RGBModifier::ADD, -1, fx->Parameter1 >> 8, fx->Parameter1 >> 16, fx->Parameter1 >> 24); @@ -951,7 +951,7 @@ { if (0) printf( "fx_set_color_pulse_rgb (%2d): RGB: %x, Location: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - ieByte location = fx->Parameter2 & 0xff; + ieDword location = fx->Parameter2 & 0xff; int speed = (fx->Parameter2 >> 16) & 0xFF; target->SetColorMod(location, RGBModifier::ADD, speed, fx->Parameter1 >> 8, fx->Parameter1 >> 16, @@ -1634,7 +1634,7 @@ { if (0) printf( "fx_darken_rgb (%2d): RGB: %d, Location and speed: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - ieByte location = fx->Parameter2 & 0xff; + ieDword location = fx->Parameter2 & 0xff; target->SetColorMod(location, RGBModifier::TINT, -1, fx->Parameter1 >> 8, fx->Parameter1 >> 16, fx->Parameter1 >> 24); return FX_APPLIED; @@ -1644,7 +1644,7 @@ { if (0) printf( "fx_glow_rgb (%2d): RGB: %d, Location and speed: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - ieByte location = fx->Parameter2 & 0xff; + ieDword location = fx->Parameter2 & 0xff; target->SetColorMod(location, RGBModifier::BRIGHTEN, -1, fx->Parameter1 >> 8, fx->Parameter1 >> 16, fx->Parameter1 >> 24); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-04-28 14:24:01
|
Revision: 4618 http://gemrb.svn.sourceforge.net/gemrb/?rev=4618&view=rev Author: avenger_teambg Date: 2007-04-28 07:24:01 -0700 (Sat, 28 Apr 2007) Log Message: ----------- fixed some buffer overflow/uninitialized memory Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Map.cpp gemrb/trunk/gemrb/plugins/GAMImporter/GAMImp.cpp Modified: gemrb/trunk/gemrb/plugins/Core/Map.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Map.cpp 2007-04-28 13:42:42 UTC (rev 4617) +++ gemrb/trunk/gemrb/plugins/Core/Map.cpp 2007-04-28 14:24:01 UTC (rev 4618) @@ -183,20 +183,12 @@ } if (j>0) { SpawnGroup *creatures = new SpawnGroup(j); -/* - ieResRef *creatures = (ieResRef *) malloc( sizeof(ieResRef)*(j+1) ); - //count of creatures - *(ieDword *) creatures = (ieDword) j; -*/ creatures->Level = (ieDword) atoi( tab->QueryField(i,0) ); //difficulty -/* - *(((ieDword *) creatures)+1) = (ieDword) atoi( tab->QueryField(i,0) ); -*/ for (;j;j--) { - strnlwrcpy( creatures->ResRefs[j-1], tab->QueryField(j,i), sizeof( ieResRef ) ); + strnlwrcpy( creatures->ResRefs[j-1], tab->QueryField(j,i), 8 ); } - strnlwrcpy( GroupName, tab->GetColumnName( i ), 8); + strnlwrcpy( GroupName, tab->GetColumnName( i ), 8 ); Spawns.SetAt( GroupName, (void*) creatures ); } } Modified: gemrb/trunk/gemrb/plugins/GAMImporter/GAMImp.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/GAMImporter/GAMImp.cpp 2007-04-28 13:42:42 UTC (rev 4617) +++ gemrb/trunk/gemrb/plugins/GAMImporter/GAMImp.cpp 2007-04-28 14:24:01 UTC (rev 4618) @@ -146,6 +146,7 @@ MazeOffset = 0; str->ReadDword( &newGame->Reputation ); str->ReadResRef( newGame->CurrentArea ); // FIXME: see above + memcpy(newGame->AnotherArea, newGame->CurrentArea, sizeof(ieResRef) ); str->ReadDword( &newGame->ControlStatus ); str->ReadDword( &KillVarsCount ); //this is still unknown str->ReadDword( &FamiliarsOffset ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-04-30 16:15:24
|
Revision: 4624 http://gemrb.svn.sourceforge.net/gemrb/?rev=4624&view=rev Author: avenger_teambg Date: 2007-04-30 09:15:20 -0700 (Mon, 30 Apr 2007) Log Message: ----------- quick hack to fix projectile index inconsistency Modified Paths: -------------- gemrb/trunk/gemrb/plugins/ITMImporter/ITMImp.cpp gemrb/trunk/gemrb/plugins/SPLImporter/SPLImp.cpp Modified: gemrb/trunk/gemrb/plugins/ITMImporter/ITMImp.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/ITMImporter/ITMImp.cpp 2007-04-30 16:05:51 UTC (rev 4623) +++ gemrb/trunk/gemrb/plugins/ITMImporter/ITMImp.cpp 2007-04-30 16:15:20 UTC (rev 4624) @@ -197,6 +197,11 @@ str->ReadWord( &eh->ChargeDepletion ); str->ReadDword( &eh->RechargeFlags ); str->ReadWord( &eh->ProjectileAnimation ); + //for some odd reasons 0 and 1 are the same + if (eh->ProjectileAnimation) { + eh->ProjectileAnimation--; + } + unsigned int i; //msvc6.0 can't cope with index variable scope for (i = 0; i < 3; i++) { Modified: gemrb/trunk/gemrb/plugins/SPLImporter/SPLImp.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/SPLImporter/SPLImp.cpp 2007-04-30 16:05:51 UTC (rev 4623) +++ gemrb/trunk/gemrb/plugins/SPLImporter/SPLImp.cpp 2007-04-30 16:15:20 UTC (rev 4624) @@ -167,6 +167,10 @@ str->ReadWord( &eh->ChargeDepletion ); str->ReadWord( &eh->ProjectileAnimation ); + //for some odd reasons 0 and 1 are the same + if (eh->ProjectileAnimation) { + eh->ProjectileAnimation--; + } eh->features = core->GetFeatures( eh->FeatureCount ); str->Seek( s->FeatureBlockOffset + 48*eh->FeatureOffset, GEM_STREAM_START ); for (unsigned int i = 0; i < eh->FeatureCount; i++) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-04-30 16:28:58
|
Revision: 4625 http://gemrb.svn.sourceforge.net/gemrb/?rev=4625&view=rev Author: avenger_teambg Date: 2007-04-30 09:28:58 -0700 (Mon, 30 Apr 2007) Log Message: ----------- improved projectiles (face target, triggered projectiles, travel bam) improved vvcs (face target) improved casting at point Modified Paths: -------------- gemrb/trunk/gemrb/plugins/ACMImporter/ACMImp.cpp gemrb/trunk/gemrb/plugins/Core/Actions.cpp gemrb/trunk/gemrb/plugins/Core/ActorBlock.cpp gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp gemrb/trunk/gemrb/plugins/Core/EffectQueue.h gemrb/trunk/gemrb/plugins/Core/GameControl.cpp gemrb/trunk/gemrb/plugins/Core/GameScript.cpp gemrb/trunk/gemrb/plugins/Core/Interface.cpp gemrb/trunk/gemrb/plugins/Core/Map.cpp gemrb/trunk/gemrb/plugins/Core/Map.h gemrb/trunk/gemrb/plugins/Core/Projectile.cpp gemrb/trunk/gemrb/plugins/Core/Projectile.h gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp gemrb/trunk/gemrb/plugins/Core/Spell.cpp gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp gemrb/trunk/gemrb/plugins/PROImporter/PROImp.cpp Modified: gemrb/trunk/gemrb/plugins/ACMImporter/ACMImp.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/ACMImporter/ACMImp.cpp 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/ACMImporter/ACMImp.cpp 2007-04-30 16:28:58 UTC (rev 4625) @@ -493,7 +493,7 @@ } for (i = 0; i < MAX_STREAMS; i++) { - if (!streams[i].free) { + if (!streams[i].free && alIsSource(streams[i].Source)) { alGetSourcei( streams[i].Source, AL_SOURCE_STATE, &state ); if (state == AL_STOPPED) { alDeleteSources( 1, &streams[i].Source ); Modified: gemrb/trunk/gemrb/plugins/Core/Actions.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-04-30 16:28:58 UTC (rev 4625) @@ -2123,13 +2123,6 @@ return; } - //parse target - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - //set target Sender->CastSpellPoint( spellres, parameters->pointParameter, true ); @@ -2190,13 +2183,6 @@ return; } - //parse target - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - //set target Sender->CastSpellPoint (spellres, parameters->pointParameter, false); @@ -2221,12 +2207,17 @@ Sender->ReleaseCurrentAction(); return; } + if (Sender->Type == ST_ACTOR) { + Actor *actor = (Actor *) Sender; + actor->SetStance (IE_ANI_CONJURE); + } if (tar->Type==ST_ACTOR) { Sender->LastTarget=tar->GetGlobalID(); + Sender->CastSpellEnd(spellres); } else { GetPositionFromScriptable(tar, Sender->LastTargetPos, false); + Sender->CastSpellPointEnd(spellres); } - Sender->CastSpellPointEnd(spellres); Sender->ReleaseCurrentAction(); } @@ -2241,13 +2232,12 @@ return; } - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } Sender->LastTargetPos=parameters->pointParameter; if (Sender->Type == ST_ACTOR) { + if (Sender->GetInternalFlag()&IF_STOPATTACK) { + Sender->ReleaseCurrentAction(); + return; + } Actor *actor = (Actor *) Sender; actor->SetStance (IE_ANI_CONJURE); } @@ -2276,7 +2266,13 @@ Actor *actor = (Actor *) Sender; actor->SetStance (IE_ANI_CONJURE); } - Sender->CastSpellPointEnd(spellres); + if (tar->Type==ST_ACTOR) { + Sender->LastTarget=tar->GetGlobalID(); + Sender->CastSpellEnd(spellres); + } else { + GetPositionFromScriptable(tar, Sender->LastTargetPos, false); + Sender->CastSpellPointEnd(spellres); + } Sender->ReleaseCurrentAction(); } @@ -2290,7 +2286,6 @@ return; } tar->Hide(); - //tar->Active &=~(SCR_ACTIVE|SCR_VISIBLE); } void GameScript::MakeGlobal(Scriptable* Sender, Action* /*parameters*/) Modified: gemrb/trunk/gemrb/plugins/Core/ActorBlock.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/ActorBlock.cpp 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/Core/ActorBlock.cpp 2007-04-30 16:28:58 UTC (rev 4625) @@ -894,7 +894,10 @@ ClearPath(); if (!steps) return; - path = area->GetLine( Pos, steps, orient, Pass ); + Point p = Pos; + p.x/=16; + p.y/=14; + path = area->GetLine( p, steps, orient, Pass ); } void Movable::DoStep(unsigned int walk_speed) Modified: gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp 2007-04-30 16:28:58 UTC (rev 4625) @@ -390,7 +390,7 @@ } } -bool EffectQueue::AddEffect(Effect* fx, Actor* self, Actor* pretarget) +bool EffectQueue::AddEffect(Effect* fx, Actor* self, Actor* pretarget, Point &dest) { int i; Game *game; @@ -399,12 +399,16 @@ switch (fx->Target) { case FX_TARGET_ORIGINAL: + fx->PosX=self->Pos.x; + fx->PosY=self->Pos.y; flg = self->fxqueue.ApplyEffect( self, fx, true ); if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { self->fxqueue.AddEffect( fx ); } break; case FX_TARGET_SELF: + fx->PosX=dest.x; + fx->PosY=dest.y; flg = self->fxqueue.ApplyEffect( self, fx, true ); if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { self->fxqueue.AddEffect( fx ); @@ -412,6 +416,8 @@ break; case FX_TARGET_PRESET: + fx->PosX=pretarget->Pos.x; + fx->PosY=pretarget->Pos.y; flg = self->fxqueue.ApplyEffect( pretarget, fx, true ); if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { pretarget->fxqueue.AddEffect( fx ); @@ -422,6 +428,8 @@ game=core->GetGame(); for (i = game->GetPartySize(true); i >= 0; i--) { Actor* actor = game->GetPC( i, true ); + fx->PosX=actor->Pos.x; + fx->PosY=actor->Pos.y; self->fxqueue.ApplyEffect( actor, fx, true ); if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { actor->fxqueue.AddEffect( fx ); @@ -434,6 +442,8 @@ map=self->GetCurrentArea(); for (i = map->GetActorCount(true); i >= 0; i--) { Actor* actor = map->GetActor( i, true ); + fx->PosX=actor->Pos.x; + fx->PosY=actor->Pos.y; self->fxqueue.ApplyEffect( actor, fx, true ); if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { actor->fxqueue.AddEffect( fx ); @@ -446,6 +456,8 @@ map=self->GetCurrentArea(); for (i = map->GetActorCount(false); i >= 0; i--) { Actor* actor = map->GetActor( i, false ); + fx->PosX=actor->Pos.x; + fx->PosY=actor->Pos.y; self->fxqueue.ApplyEffect( actor, fx, true ); //GetActorCount can now return all nonparty critters //if (actor->InParty) continue; @@ -469,7 +481,7 @@ //this is where effects from spells first get in touch with the target //the effects are currently NOT in the target's fxqueue, those that stick //will get copied (hence the fxqueue.AddEffect call) -void EffectQueue::AddAllEffects(Actor* target) +void EffectQueue::AddAllEffects(Actor* target, Point &destination) { // pre-roll dice for fx needing them and stow them in the effect ieDword random_value = core->Roll( 1, 100, 0 ); @@ -480,7 +492,7 @@ (*f)->random_value = random_value; //if applyeffect returns true, we stop adding the future effects //this is to simulate iwd2's on the fly spell resistance - if(AddEffect(*f, Owner, target)) { + if(AddEffect(*f, Owner, target, destination)) { break; } } @@ -703,8 +715,10 @@ ieDword GameTime = core->GetGame()->GameTime; if (first_apply) { - fx->PosX = target->Pos.x; - fx->PosY = target->Pos.y; + if ((fx->PosX==0xffff) && (fx->PosY==0xffff)) { + fx->PosX = (ieWord) target->Pos.x; + fx->PosY = (ieWord) target->Pos.y; + } //the effect didn't pass the probability check if (!check_probability(fx) ) { fx->TimingMode=FX_DURATION_JUST_EXPIRED; @@ -1244,7 +1258,7 @@ if (!map->IsVisible(actor->Pos, pos)) { continue; } - AddAllEffects(actor); + AddAllEffects(actor, actor->Pos); } } Modified: gemrb/trunk/gemrb/plugins/Core/EffectQueue.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/EffectQueue.h 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/Core/EffectQueue.h 2007-04-30 16:28:58 UTC (rev 4625) @@ -84,6 +84,7 @@ #define STAT_SUB(stat, mod) target->SetStat( stat, STAT_GET( stat ) - ( mod ), 0 ) #define STAT_BIT_OR(stat, mod) target->SetStat( stat, STAT_GET( stat ) | ( mod ), 0 ) #define STAT_SET(stat, mod) target->SetStat( stat, ( mod ), 0 ) +#define STAT_SET_PCF(stat, mod) target->SetStat( stat, ( mod ), 1 ) #define STAT_MUL(stat, mod) target->SetStat( stat, STAT_GET(stat) * ( mod ) / 100, 0 ) //if an effect sticks around #define STATE_CURE( mod ) target->Modified[ IE_STATE_ID ] &= ~(ieDword) ( mod ) @@ -154,12 +155,12 @@ * Returns true is successful. fx is just a reference, AddEffect() * will malloc its own copy */ bool AddEffect(Effect* fx); - bool AddEffect(Effect* fx, Actor* self, Actor* pretarget); + bool AddEffect(Effect* fx, Actor* self, Actor* pretarget, Point &dest); /** Removes first Effect matching fx from the queue. * Effects are matched based on their contents */ bool RemoveEffect(Effect* fx); - void AddAllEffects(Actor* target); + void AddAllEffects(Actor* target, Point &dest); void ApplyAllEffects(Actor* target); /* returns true if the process should abort applying a stack of effects */ bool ApplyEffect(Actor* target, Effect* fx, bool first_apply); Modified: gemrb/trunk/gemrb/plugins/Core/GameControl.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameControl.cpp 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/Core/GameControl.cpp 2007-04-30 16:28:58 UTC (rev 4625) @@ -947,15 +947,26 @@ } spellCount--; if (spellOrItem>=0) { + sprintf(Tmp, "NIDSpecial8()"); + } else { + //using item on target + sprintf(Tmp, "NIDSpecial7()"); + } + Action* action = GenerateAction( Tmp ); + action->pointParameter=tgt; + if (spellOrItem>=0) + { CREMemorizedSpell *si; //spell casting at target si = source->spellbook.GetMemorizedSpell(spellOrItem, spellSlot, spellIndex); - sprintf(Tmp, "SpellPoint([%d.%d], %s)", tgt.x, tgt.y, si->SpellResRef ); - } else { - //using item on target - sprintf(Tmp, "UseItemPoint(\"\",[%d.%d],%d,%d)", tgt.x,tgt.y,spellIndex, spellSlot ); + sprintf(action->string0Parameter,"%.8s",si->SpellResRef); } - source->AddAction( GenerateAction( Tmp) ); + else + { + action->int0Parameter=spellSlot; + action->int1Parameter=spellIndex; + } + source->AddAction( action ); if (!spellCount) { target_mode = TARGET_MODE_NONE; } @@ -977,7 +988,6 @@ sprintf(Tmp, "NIDSpecial5()"); } Action* action = GenerateActionDirect( Tmp, tgt); - source->AddAction( action ); if (spellOrItem>=0) { CREMemorizedSpell *si; @@ -990,6 +1000,7 @@ action->int0Parameter=spellSlot; action->int1Parameter=spellIndex; } + source->AddAction( action ); if (!spellCount) { target_mode = TARGET_MODE_NONE; } Modified: gemrb/trunk/gemrb/plugins/Core/GameScript.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/GameScript.cpp 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/Core/GameScript.cpp 2007-04-30 16:28:58 UTC (rev 4625) @@ -652,6 +652,8 @@ {"nidspecial4", GameScript::ProtectObject,AF_BLOCKING|AF_DIRECT|AF_ALIVE}, {"nidspecial5", GameScript::UseItem, AF_BLOCKING|AF_DIRECT|AF_ALIVE}, {"nidspecial6", GameScript::Spell, AF_BLOCKING|AF_DIRECT|AF_ALIVE}, + {"nidspecial7", GameScript::UseItemPoint, AF_BLOCKING|AF_ALIVE}, + {"nidspecial8", GameScript::SpellPoint, AF_BLOCKING|AF_ALIVE}, {"noaction", GameScript::NoAction, 0}, {"opendoor", GameScript::OpenDoor,AF_BLOCKING}, {"panic", GameScript::Panic, 0}, @@ -3095,6 +3097,7 @@ if (tmp && tmp->objectFields[0]==-1) { tmp->objectFields[1] = object->globalID; } + action->pointParameter.empty(); return action; } Modified: gemrb/trunk/gemrb/plugins/Core/Interface.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Interface.cpp 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/Core/Interface.cpp 2007-04-30 16:28:58 UTC (rev 4625) @@ -4872,7 +4872,7 @@ actor = caster; } fxqueue->SetOwner( caster ); - fxqueue->AddAllEffects(actor); + fxqueue->AddAllEffects(actor, actor->Pos); } delete fxqueue; } @@ -4902,7 +4902,7 @@ actor = caster; } fxqueue->SetOwner( caster ); - fxqueue->AddAllEffects( actor ); + fxqueue->AddAllEffects( actor, actor->Pos ); } delete fxqueue; } Modified: gemrb/trunk/gemrb/plugins/Core/Map.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Map.cpp 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/Core/Map.cpp 2007-04-30 16:28:58 UTC (rev 4625) @@ -1949,23 +1949,30 @@ /* Use this function when you target something by a straight line projectile (like a lightning bolt, arrow, etc) */ + PathNode* Map::GetLine(Point &start, Point &dest, int flags) { int Orientation = GetOrient(start, dest); - int Steps = Distance(start, dest); - - return GetLine(start, dest, Steps, Orientation, flags); + return GetLine(start, dest, 1, Orientation, flags); } PathNode* Map::GetLine(Point &start, int Steps, int Orientation, int flags) { - Point dest; + Point dest=start; + int count = Steps; + while(count) { + int st = Steps>MaxVisibility?MaxVisibility:Steps; + int p = VisibilityPerimeter*Orientation/MAX_ORIENT; + dest.x += VisibilityMasks[Steps][p].x; + dest.y += VisibilityMasks[Steps][p].y; + count-=st; + } //FIXME: calculate dest based on distance and orientation return GetLine(start, dest, Steps, Orientation, flags); } -PathNode* Map::GetLine(Point &start, Point &dest, int Steps, int Orientation, int flags) +PathNode* Map::GetLine(Point &start, Point &dest, int Speed, int Orientation, int flags) { PathNode* StartNode = new PathNode; PathNode *Return = StartNode; @@ -1975,23 +1982,31 @@ StartNode->y = start.y; StartNode->orient = Orientation; - int Max = Steps; - while (Steps--) { - int x,y; + int Count = 0; + int Max = Distance(start,dest); + for (int Steps = 0; Steps<Max; Steps++) { + if (!Count) { + StartNode->Next = new PathNode; + StartNode->Next->Parent = StartNode; + StartNode = StartNode->Next; + StartNode->Next = NULL; + Count=Speed; + } else { + Count--; + } - StartNode->Next = new PathNode; - StartNode->Next->Parent = StartNode; - StartNode = StartNode->Next; - StartNode->Next = NULL; - x = (start.x + dest.x) * Steps / Max; - y = (start.y + dest.y) * Steps / Max; - StartNode->x = (ieWord) x; - StartNode->y = (ieWord) y; + Point p; + p.x = (ieWord) start.x + ((dest.x - start.x) * Steps / Max); + p.y = (ieWord) start.y + ((dest.y - start.y) * Steps / Max); + StartNode->x = p.x; + StartNode->y = p.y; StartNode->orient = Orientation; - bool wall = !( GetBlocked( x, y ) & PATH_MAP_PASSABLE ); + bool wall = !( GetBlocked( p ) & PATH_MAP_PASSABLE ); if (wall) switch (flags) { case GL_REBOUND: Orientation = (Orientation + 8) &15; + //recalculate dest (mirror it) + // break; case GL_PASS: break; Modified: gemrb/trunk/gemrb/plugins/Core/Map.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Map.h 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/Core/Map.h 2007-04-30 16:28:58 UTC (rev 4625) @@ -354,8 +354,9 @@ /* returns true if there is enemy visible */ bool AnyPCSeesEnemy(); /* Finds straight path from s, length l and orientation o, f=1 passes wall, f=2 rebounds from wall*/ + PathNode* GetLine(Point &start, Point &dest, int flags); PathNode* GetLine(Point &start, int Steps, int Orientation, int flags); - PathNode* GetLine(Point &start, Point &dest, int flags); + PathNode* GetLine(Point &start, Point &dest, int Steps, int Orientation, int flags); /* Finds the path which leads to d */ PathNode* FindPath(const Point &s, const Point &d, int MinDistance = 0); /* returns false if point isn't visible on visibility/explored map */ @@ -416,7 +417,6 @@ void SetupNode(unsigned int x, unsigned int y, unsigned int Cost); //actor uses travel region void UseExit(Actor *pc, InfoPoint *ip); - PathNode* GetLine(Point &start, Point &dest, int Steps, int Orientation, int flags); //separated position adjustment, so their order could be randomised */ bool AdjustPositionX(Point &goal, unsigned int radius); bool AdjustPositionY(Point &goal, unsigned int radius); Modified: gemrb/trunk/gemrb/plugins/Core/Projectile.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Projectile.cpp 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/Core/Projectile.cpp 2007-04-30 16:28:58 UTC (rev 4625) @@ -28,19 +28,22 @@ #include "Game.h" #include "ResourceMgr.h" #include "SoundMgr.h" +#include "ProjectileServer.h" extern Interface* core; #ifdef WIN32 extern HANDLE hConsole; #endif +static ieByte SixteenToNine[MAX_ORIENT]={0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1}; +static ieByte SixteenToFive[MAX_ORIENT]={0,0,1,1,2,2,3,3,4,4,3,3,2,2,1,1}; + Projectile::Projectile() { autofree = false; Extension = NULL; area = NULL; - Pos.x = 0; - Pos.y = 0; + Pos.empty(); Destination = Pos; Orientation = 0; NewOrientation = 0; @@ -82,22 +85,8 @@ return node; } -//Pass means passing/rebounding/extinguishing on walls -void Projectile::MoveLine(int steps, int Pass, ieDword orient) +void Projectile::CreateAnimations(Animation **anims, ieResRef bamres, int Seq) { - //call this with destination - if (path) { - return; - } - if (!steps) { - Pos = Destination; - return; - } - path = area->GetLine( Pos, steps, orient, Pass ); -} - -void Projectile::CreateAnimations(Animation **anims, ieResRef bamres) -{ AnimationFactory* af = ( AnimationFactory* ) core->GetResourceMgr()->GetFactoryResource( bamres, IE_BAM_CLASS_ID, IE_NORMAL ); @@ -105,8 +94,30 @@ if (!af) { return; } + //this hack is needed because bioware .pro files are sometimes + //reporting bigger face count than possible by the animation + int Max = af->GetCycleCount(); + if (Aim>Max) Aim=Max; for (int Cycle = 0; Cycle<MAX_ORIENT; Cycle++) { - Animation* a = af->GetCycle( Cycle ); + int c; + switch(Aim) { + default: + c = Seq; + break; + case 5: + c = SixteenToFive[Cycle]; + break; + case 9: + c = SixteenToNine[Cycle]; + break; + case 16: + c=Cycle; + break; + } + Animation* a = af->GetCycle( c ); + if (a && c!=Cycle) { + a->MirrorAnimation(); + } anims[Cycle] = a; } } @@ -119,9 +130,9 @@ memset(travel,0,sizeof(travel)); memset(shadow,0,sizeof(shadow)); light = NULL; - CreateAnimations(travel, BAMRes1); + CreateAnimations(travel, BAMRes1, Seq1); if (TFlags&PTF_SHADOW) { - CreateAnimations(shadow, BAMRes2); + CreateAnimations(shadow, BAMRes2, Seq2); } if (TFlags&PTF_LIGHT) { //light = CreateLight(LightX, LightY, LightZ); @@ -142,9 +153,9 @@ return; } int steps = Distance(Pos, target); - - if (steps) { - SetTarget(target->Pos); + //48 = 6*8 + if (steps>=48) { + NextTarget(target->Pos); return; } } @@ -152,24 +163,36 @@ //reached target if (!Extension) { phase = P_EXPIRED; + //there could be no-effect projectiles + if (!effects) return; + + Actor *target; if (Target) { - Actor *target = area->GetActorByGlobalID(Target); + target = area->GetActorByGlobalID(Target); if (!target) { return; } - //deliver payload to target Actor *original = area->GetActorByGlobalID(Caster); effects->SetOwner(original?original:target); - effects->AddAllEffects(target); - //not simply nulling it, addalleffects copies them - delete effects; - effects = NULL; - return; + } else { + //the target is the original caster + //in case of single point area target (dimension door) + target = area->GetActorByGlobalID(Caster); + if (!target) { + return; + } + effects->SetOwner(target); } - //get target + effects->AddAllEffects(target, Destination); + delete effects; + effects = NULL; return; } - phase = P_TRIGGER; + if (Extension->AFlags&PAF_TRIGGER) { + phase = P_TRIGGER; + } else { + phase = P_EXPLODING; + } } void Projectile::DoStep(unsigned int walk_speed) @@ -178,6 +201,12 @@ ChangePhase(); return; } + if (Pos==Destination) { + ClearPath(); + ChangePhase(); + return; + } + ieDword time = core->GetGame()->Ticks; if (!step) { step = path; @@ -190,8 +219,8 @@ SetOrientation (step->orient, false); - Pos.x = ( step->x * 16 ) + 8; - Pos.y = ( step->y * 12 ) + 6; + Pos.x=step->x; + Pos.y=step->y; if (!step->Next) { ClearPath(); NewOrientation = Orientation; @@ -203,16 +232,16 @@ } if (step->Next->x > step->x) Pos.x += ( unsigned short ) - ( ( ( ( ( step->Next->x * 16 ) + 8 ) - Pos.x ) * ( time - timeStartStep ) ) / walk_speed ); + ( ( step->Next->x - Pos.x ) * ( time - timeStartStep ) / walk_speed ); else Pos.x -= ( unsigned short ) - ( ( ( Pos.x - ( ( step->Next->x * 16 ) + 8 ) ) * ( time - timeStartStep ) ) / walk_speed ); + ( ( Pos.x - step->Next->x ) * ( time - timeStartStep ) / walk_speed ); if (step->Next->y > step->y) Pos.y += ( unsigned short ) - ( ( ( ( ( step->Next->y * 12 ) + 6 ) - Pos.y ) * ( time - timeStartStep ) ) / walk_speed ); + ( ( step->Next->y - Pos.y ) * ( time - timeStartStep ) / walk_speed ); else Pos.y -= ( unsigned short ) - ( ( ( Pos.y - ( ( step->Next->y * 12 ) + 6 ) ) * ( time - timeStartStep ) ) / walk_speed ); + ( ( Pos.y - step->Next->y ) * ( time - timeStartStep ) / walk_speed ); } void Projectile::SetCaster(ieDword caster) @@ -220,13 +249,28 @@ Caster=caster; } -void Projectile::SetTarget(Point &p) +void Projectile::NextTarget(Point &p) { ClearPath(); Destination = p; - MoveLine( Speed, true, GetOrient(p, Pos) ); + //call this with destination + if (path) { + return; + } + if (!Speed) { + Pos = Destination; + return; + } + Orientation = GetOrient(Pos, Destination); + path = area->GetLine( Pos, Destination, Speed, Orientation, GL_PASS ); } +void Projectile::SetTarget(Point &p) +{ + Target = 0; + NextTarget(p); +} + void Projectile::SetTarget(ieDword tar) { Target = tar; @@ -235,7 +279,7 @@ phase = P_EXPIRED; return; } - SetTarget(target->Pos); + NextTarget(target->Pos); } void Projectile::MoveTo(Map *map, Point &Des) @@ -247,10 +291,6 @@ void Projectile::ClearPath() { - //this is to make sure attackers come to us - //make sure ClearPath doesn't screw Destination (in the rare cases Destination - //is set before ClearPath - Destination = Pos; if (!path) { return; } @@ -265,7 +305,6 @@ } path = NULL; step = NULL; - //don't call ReleaseCurrentAction } //get actors covered in area of effect radius @@ -299,6 +338,9 @@ case P_UNINITED: return; case P_TRIGGER: + if (Extension->AFlags&PAF_VISIBLE) { + DrawTravel(screen); + } CheckTrigger(Extension->TriggerRadius); case P_TRAVEL: if (phase != P_EXPLODING) { @@ -335,6 +377,18 @@ } else { phase = P_EXPLODED; } + + //there is a secondary projectile + if (Extension->AFlags&PAF_SECONDARY) { + //the secondary projectile will target everyone in the area of effect + } + //the center of the explosion could be another projectile played over the target + if (Extension->FragProjIdx) { + Projectile *pro = core->GetProjectileServer()->GetProjectileByIndex(Extension->FragProjIdx); + if (pro) { + area->AddProjectile(pro, Pos, Pos); + } + } /* Video *video = core->GetVideoDriver(); */ Modified: gemrb/trunk/gemrb/plugins/Core/Projectile.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Projectile.h 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/Core/Projectile.h 2007-04-30 16:28:58 UTC (rev 4625) @@ -68,6 +68,16 @@ #define PTF_LIGHT 64 //has light shadow #define PTF_BLEND 128 //blend colours +//projectile area flags +#define PAF_VISIBLE 1 //the travel projectile is visible until explosion +#define PAF_INANIMATE 2 //target inanimates +#define PAF_TRIGGER 4 //explosion needs to be triggered +#define PAF_SYNC 8 //one explosion at a time +#define PAF_SECONDARY 16 //secondary projectiles at explosion +#define PAF_FRAGMENT 32 //fragments (charanimation) at explosion +#define PAF_TGT 64 //target party or not party +#define PAF_PARTY 128 //target party + typedef struct ProjectileExtension { ieDword AFlags; @@ -92,7 +102,7 @@ Projectile(); ~Projectile(); void InitExtension(); - void CreateAnimations(Animation **anims, ieResRef bam); + void CreateAnimations(Animation **anims, ieResRef bam, int Seq); ieWord Type; ieWord Speed; @@ -113,7 +123,7 @@ ieByte Gradients[7]; ieByte SmokeSpeed; ieByte SmokeGrad[7]; - ieByte SmokeAim; + ieByte Aim; ieWord SmokeAnimID; ieResRef TrailBAM[3]; ieWord TrailSpeed[3]; @@ -195,7 +205,6 @@ void Setup(); void ChangePhase(); void DoStep(unsigned int walk_speed); - void MoveLine(int steps, int Pass, ieDword Orient); void MoveTo(Map *map, Point &Des); void ClearPath(); //handle phases, return 0 when expired @@ -210,6 +219,7 @@ int GetTravelPos(int face); int GetShadowPos(int face); void SetPos(int face, int frame1, int frame2); + void NextTarget(Point &p); }; #endif // PROJECTILE_H Modified: gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/Core/ScriptedAnimation.cpp 2007-04-30 16:28:58 UTC (rev 4625) @@ -37,22 +37,20 @@ #define NINE 16 //nine faces (orientation) #define MAX_CYCLE_TYPE 16 -// 0 1 2 3 4 5 6 7 -static ieByte ctypes[MAX_CYCLE_TYPE]= -{ ILLEGAL, ONE, TWO, THREE, TWO|DOUBLE, ONE|FIVE, THREE|DOUBLE, ILLEGAL, -// 8 9 10 11 12 13 14 15 +static ieByte ctypes[MAX_CYCLE_TYPE]={ + ILLEGAL, ONE, TWO, THREE, TWO|DOUBLE, ONE|FIVE, THREE|DOUBLE, ILLEGAL, ILLEGAL,ONE|NINE, TWO|FIVE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,THREE|FIVE, }; static ieByte SixteenToNine[3*MAX_ORIENT]={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 9,10,11,12,13,14,15,16,17,16,15,14,13,12,11,10, - 18,19,20,21,22,23,24,25,26,25,24,23,22,21,20,19 + 18,19,20,21,22,23,24,25,26,25,24,23,22,21,20,19 }; static ieByte SixteenToFive[3*MAX_ORIENT]={ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 3, 3, 2, 2, 1, 1, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 8, 8, 7, 7, 6, 6, - 10,10,11,11,12,12,13,13,14,14,13,13,12,12,11,11 + 10,10,11,11,12,12,13,13,14,14,13,13,12,12,11,11 }; ScriptedAnimation::ScriptedAnimation() @@ -281,35 +279,65 @@ core->GetResourceMgr()->GetFactoryResource( Anim1ResRef, IE_BAM_CLASS_ID ); //no idea about vvc phases, i think they got no endphase? //they certainly got onset and hold phases - anims[P_ONSET] = af->GetCycle( ( unsigned char ) seq1 ); - if (anims[P_ONSET]) { - PrepareAnimation(anims[P_ONSET], Transparency); - //creature anims may start at random position, vvcs always start on 0 - anims[P_ONSET]->pos=0; - //vvcs are always paused - anims[P_ONSET]->gameAnimation=true; - anims[P_ONSET]->Flags |= S_ANI_PLAYONCE; - } - - anims[P_HOLD] = af->GetCycle( ( unsigned char ) seq2 ); - if (anims[P_HOLD]) { - PrepareAnimation(anims[P_HOLD], Transparency); - - anims[P_HOLD]->pos=0; - anims[P_HOLD]->gameAnimation=true; - if (!(SequenceFlags&IE_VVC_LOOP) ) { - anims[P_HOLD]->Flags |= S_ANI_PLAYONCE; + //the face target flag should be handled too + for (int i=0;i<MAX_ORIENT;i++) { + unsigned int p_hold = P_HOLD*MAX_ORIENT+i; + unsigned int p_onset = P_ONSET*MAX_ORIENT+i; + unsigned int p_release = P_RELEASE*MAX_ORIENT+i; + int c = seq1; + switch (FaceTarget) { + case 5: + c=SixteenToFive[i]; + break; + case 9: + c=SixteenToNine[i]; + break; + case 16: + c=i; + break; } + anims[p_onset] = af->GetCycle( c ); + if (anims[p_onset]) { + PrepareAnimation(anims[p_onset], Transparency); + //creature anims may start at random position, vvcs always start on 0 + anims[p_onset]->pos=0; + //vvcs are always paused + anims[p_onset]->gameAnimation=true; + anims[p_onset]->Flags |= S_ANI_PLAYONCE; + } + + c = seq2; + switch (FaceTarget) { + case 5: + c=SixteenToFive[i]; + break; + case 9: + c=SixteenToNine[i]; + break; + case 16: + c=i; + break; + } + anims[p_hold] = af->GetCycle( c ); + if (anims[p_hold]) { + PrepareAnimation(anims[p_hold], Transparency); + + anims[p_hold]->pos=0; + anims[p_hold]->gameAnimation=true; + if (!(SequenceFlags&IE_VVC_LOOP) ) { + anims[p_hold]->Flags |= S_ANI_PLAYONCE; + } + } + + anims[p_release] = af->GetCycle( ( unsigned char ) seq3 ); + if (anims[p_release]) { + PrepareAnimation(anims[p_release], Transparency); + + anims[p_release]->pos=0; + anims[p_release]->gameAnimation=true; + anims[p_release]->Flags |= S_ANI_PLAYONCE; + } } - - anims[P_RELEASE] = af->GetCycle( ( unsigned char ) seq3 ); - if (anims[P_RELEASE]) { - PrepareAnimation(anims[P_RELEASE], Transparency); - - anims[P_RELEASE]->pos=0; - anims[P_RELEASE]->gameAnimation=true; - anims[P_RELEASE]->Flags |= S_ANI_PLAYONCE; - } } //copying resource name to the object, so it could be referenced by it Modified: gemrb/trunk/gemrb/plugins/Core/Spell.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spell.cpp 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/Core/Spell.cpp 2007-04-30 16:28:58 UTC (rev 4625) @@ -106,7 +106,6 @@ } if (seh->FeatureCount) { Projectile *pro = core->GetProjectileServer()->GetProjectileByIndex(seh->ProjectileAnimation); - pro->SetEffects(GetEffectBlock(header)); return pro; } Modified: gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-04-30 16:28:58 UTC (rev 4625) @@ -2992,7 +2992,7 @@ int fx_set_sanctuary_state (Actor* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_set_sanctuary_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - STAT_SET( IE_SANCTUARY, 1); + STAT_SET_PCF( IE_SANCTUARY, 1); return FX_APPLIED; } @@ -3000,7 +3000,7 @@ int fx_set_entangle_state (Actor* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_set_entangle_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - STAT_SET( IE_ENTANGLE, 1); + STAT_SET_PCF( IE_ENTANGLE, 1); //STAT_SET(IE_MOVEMENTRATE, 0); // return FX_APPLIED; } @@ -3009,7 +3009,7 @@ int fx_set_minorglobe_state (Actor* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_set_minorglobe_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - STAT_SET( IE_MINORGLOBE, 1); + STAT_SET_PCF( IE_MINORGLOBE, 1); return FX_APPLIED; } @@ -3017,7 +3017,7 @@ int fx_set_shieldglobe_state (Actor* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_set_shieldglobe_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - STAT_SET( IE_SHIELDGLOBE, 1); + STAT_SET_PCF( IE_SHIELDGLOBE, 1); return FX_APPLIED; } @@ -3025,7 +3025,7 @@ int fx_set_web_state (Actor* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_set_web_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - STAT_SET( IE_WEB, 1); + STAT_SET_PCF( IE_WEB, 1); STAT_SET(IE_MOVEMENTRATE, 0); // return FX_APPLIED; } @@ -3034,7 +3034,7 @@ int fx_set_grease_state (Actor* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_set_grease_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - STAT_SET( IE_GREASE, 1); + STAT_SET_PCF( IE_GREASE, 1); STAT_SET(IE_MOVEMENTRATE, 3); // return FX_APPLIED; } @@ -3555,19 +3555,26 @@ int fx_play_visual_effect (Actor* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_play_visual_effect (%2d): Resource: %s Type: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 ); - if (fx->Resource[0]) { - ScriptedAnimation* vvc = core->GetScriptedAnimation(fx->Resource, false); - if (fx->Parameter2) { - //play over target - target->AddVVCell( vvc ); - } else { - //the effect should already have its position set - vvc->XPos=fx->PosX; - vvc->YPos=fx->PosY; - target->GetCurrentArea()->AddVVCell( vvc ); + if (!fx->Resource[0]) { + return FX_NOT_APPLIED; + } + ScriptedAnimation* sca = core->GetScriptedAnimation(fx->Resource, false); + if (fx->TimingMode!=FX_DURATION_INSTANT_PERMANENT) { + sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks); + } + if (fx->Parameter2) { + //play over target (sticky) + if (!target->HasVVCCell(fx->Resource) ) { + target->AddVVCell( sca ); } + return FX_APPLIED; } - return FX_APPLIED; + + //not sticky + sca->XPos=fx->PosX; + sca->YPos=fx->PosY; + target->GetCurrentArea()->AddVVCell( sca ); + return FX_NOT_APPLIED; } //d8 LevelDrainModifier Modified: gemrb/trunk/gemrb/plugins/PROImporter/PROImp.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/PROImporter/PROImp.cpp 2007-04-30 16:15:20 UTC (rev 4624) +++ gemrb/trunk/gemrb/plugins/PROImporter/PROImp.cpp 2007-04-30 16:28:58 UTC (rev 4625) @@ -87,7 +87,7 @@ str->Read( s->Gradients, 7); str->Read( &s->SmokeSpeed, 1); str->Read( s->SmokeGrad, 7); - str->Read( &s->SmokeAim, 1); + str->Read( &s->Aim, 1); str->ReadWord( &s->SmokeAnimID); str->ReadResRef( s->TrailBAM[0] ); str->ReadResRef( s->TrailBAM[1] ); @@ -112,11 +112,19 @@ str->ReadResRef( e->SoundRes ); //explosion sound str->ReadWord( &e->Delay ); str->ReadWord( &e->FragAnimID ); + //this projectile index shouldn't be adjusted like the others!!! str->ReadWord( &e->FragProjIdx ); str->Read( &e->ExplosionCount,1 ); - str->Read( &e->ExplType,1); //the area puff type (flames, puffs, clouds) fireball.ids + //the area puff type (flames, puffs, clouds) fireball.ids + //gemrb will need a fireball.2da for this + str->Read( &e->ExplType,1); str->ReadWord( &e->ExplColor); str->ReadWord( &e->ExplProjIdx); + //i don't know why is this here + if (e->ExplProjIdx) { + e->ExplProjIdx--; + } + str->ReadResRef( e->VVCRes ); str->ReadWord( &e->ConeWidth); //we skip the rest This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
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. |
From: <ave...@us...> - 2007-05-01 19:37:42
|
Revision: 4632 http://gemrb.svn.sourceforge.net/gemrb/?rev=4632&view=rev Author: avenger_teambg Date: 2007-05-01 12:37:42 -0700 (Tue, 01 May 2007) Log Message: ----------- added the spellbookiconhack feature (replace last letter of spellbookicon resref in spells in bg2/tob) a little cleanup in acmimporter Modified Paths: -------------- gemrb/trunk/gemrb/plugins/ACMImporter/ACMImp.cpp gemrb/trunk/gemrb/plugins/Core/Interface.cpp gemrb/trunk/gemrb/plugins/SPLImporter/SPLImp.cpp Modified: gemrb/trunk/gemrb/plugins/ACMImporter/ACMImp.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/ACMImporter/ACMImp.cpp 2007-05-01 19:35:52 UTC (rev 4631) +++ gemrb/trunk/gemrb/plugins/ACMImporter/ACMImp.cpp 2007-05-01 19:37:42 UTC (rev 4632) @@ -440,8 +440,11 @@ ALenum error; ALint state; + ieDword volume = 100; if (flags & GEM_SND_SPEECH) { + //speech has a single channel, if a new speech started + //we stop the previous one if (speech.free || !alIsSource( speech.Source )) { alGenSources( 1, &speech.Source ); if (( error = alGetError() ) != AL_NO_ERROR) { @@ -461,7 +464,6 @@ } printf("***speech.free: %d source:%d\n", speech.free,speech.Source); } - ieDword volume; core->GetDictionary()->Lookup( "Volume Voices", volume ); alSourcef( speech.Source, AL_GAIN, 0.01f * volume ); alSourcei( speech.Source, AL_SOURCE_RELATIVE, flags & GEM_SND_RELATIVE ); @@ -470,49 +472,51 @@ speech.Buffer = Buffer; alSourcePlay( speech.Source ); return time_length; - } else { - alGenSources( 1, &Source ); - if (( error = alGetError() ) != AL_NO_ERROR) { - DisplayALError( "[ACMImp::Play] alGenSources : ", error ); - return 0; - } + } - alSourcef( Source, AL_PITCH, 1.0f ); - alSourcefv( Source, AL_VELOCITY, SourceVel ); - alSourcei( Source, AL_LOOPING, 0 ); - alSourcef( Source, AL_REFERENCE_DISTANCE, REFERENCE_DISTANCE ); - ieDword volume; - core->GetDictionary()->Lookup( "Volume SFX", volume ); - alSourcef( Source, AL_GAIN, 0.01f * volume ); - alSourcei( Source, AL_SOURCE_RELATIVE, flags & GEM_SND_RELATIVE ); - alSourcefv( Source, AL_POSITION, SourcePos ); - alSourcei( Source, AL_BUFFER, Buffer ); + // not speech + alGenSources( 1, &Source ); + if (( error = alGetError() ) != AL_NO_ERROR) { + //failed to generate new sound source + DisplayALError( "[ACMImp::Play] alGenSources : ", error ); + return 0; + } - if (alGetError() != AL_NO_ERROR) { - return 0; - } + alSourcef( Source, AL_PITCH, 1.0f ); + alSourcefv( Source, AL_VELOCITY, SourceVel ); + alSourcei( Source, AL_LOOPING, 0 ); + alSourcef( Source, AL_REFERENCE_DISTANCE, REFERENCE_DISTANCE ); + core->GetDictionary()->Lookup( "Volume SFX", volume ); + alSourcef( Source, AL_GAIN, 0.01f * volume ); + alSourcei( Source, AL_SOURCE_RELATIVE, flags & GEM_SND_RELATIVE ); + alSourcefv( Source, AL_POSITION, SourcePos ); + alSourcei( Source, AL_BUFFER, Buffer ); - for (i = 0; i < MAX_STREAMS; i++) { - if (!streams[i].free && alIsSource(streams[i].Source)) { - alGetSourcei( streams[i].Source, AL_SOURCE_STATE, &state ); - if (state == AL_STOPPED) { - alDeleteSources( 1, &streams[i].Source ); - alDeleteBuffers( 1, &streams[i].Buffer ); - streams[i].Buffer = Buffer; - streams[i].Source = Source; - alSourcePlay( Source ); - return time_length; - } - } else { + if (alGetError() != AL_NO_ERROR) { + return 0; + } + + for (i = 0; i < MAX_STREAMS; i++) { + if (!streams[i].free && alIsSource(streams[i].Source)) { + alGetSourcei( streams[i].Source, AL_SOURCE_STATE, &state ); + if (state == AL_STOPPED) { + alDeleteSources( 1, &streams[i].Source ); + alDeleteBuffers( 1, &streams[i].Buffer ); streams[i].Buffer = Buffer; streams[i].Source = Source; - streams[i].free = false; alSourcePlay( Source ); return time_length; } + } else { + streams[i].Buffer = Buffer; + streams[i].Source = Source; + streams[i].free = false; + alSourcePlay( Source ); + return time_length; } } + //failed to assign new sound alDeleteSources( 1, &Source ); alDeleteBuffers( 1, &Buffer ); Modified: gemrb/trunk/gemrb/plugins/Core/Interface.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Interface.cpp 2007-05-01 19:35:52 UTC (rev 4631) +++ gemrb/trunk/gemrb/plugins/Core/Interface.cpp 2007-05-01 19:37:42 UTC (rev 4632) @@ -2230,6 +2230,7 @@ SetFeature( ini->GetKeyAsInt( "resources", "MagicBit", 0 ), GF_MAGICBIT ); SetFeature( ini->GetKeyAsInt( "resources", "CheckAbilities", 0 ), GF_CHECK_ABILITIES ); SetFeature( ini->GetKeyAsInt( "resources", "ChallengeRating", 0 ), GF_CHALLENGERATING ); + SetFeature( ini->GetKeyAsInt( "resources", "SpellBookIconHack", 0), GF_SPELLBOOKICONHACK ); ForceStereo = ini->GetKeyAsInt( "resources", "ForceStereo", 0 ); FreeInterface( ini ); Modified: gemrb/trunk/gemrb/plugins/SPLImporter/SPLImp.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/SPLImporter/SPLImp.cpp 2007-05-01 19:35:52 UTC (rev 4631) +++ gemrb/trunk/gemrb/plugins/SPLImporter/SPLImp.cpp 2007-05-01 19:37:42 UTC (rev 4632) @@ -83,6 +83,12 @@ str->ReadDword( &s->SpellLevel ); str->ReadWord( &s->unknown5 ); str->ReadResRef( s->SpellbookIcon ); + //this hack is needed in ToB at least + if (core->HasFeature(GF_SPELLBOOKICONHACK)) { + i=strlen(s->SpellbookIcon); + if (i) s->SpellbookIcon[i]='C'; + } + str->ReadWord( &s->unknown6 ); str->ReadDword( &s->unknown7 ); str->ReadDword( &s->unknown8 ); @@ -123,19 +129,7 @@ for (i = 0; i < s->CastingFeatureCount; i++) { GetFeature(s, s->casting_features+i); } -/* - DataStream* bamfile = core->GetResourceMgr()->GetResource( s->SpellbookIcon, IE_BAM_CLASS_ID ); - if (!core->IsAvailable( IE_BAM_CLASS_ID )) { - printf( "[SPLImporter]: No BAM Importer Available.\n" ); - return NULL; - } - AnimationMgr* bam = ( AnimationMgr* ) - core->GetInterface( IE_BAM_CLASS_ID ); - bam->Open( bamfile ); - s->SpellIconBAM = bam; -*/ - return s; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-05-06 07:21:49
|
Revision: 4642 http://gemrb.svn.sourceforge.net/gemrb/?rev=4642&view=rev Author: avenger_teambg Date: 2007-05-06 00:21:49 -0700 (Sun, 06 May 2007) Log Message: ----------- fixed kit unusabilities (handle bg2 style hacked kits) implemented AddKit action almost fixed AC effect where some AC effects should always enter the queue first Modified Paths: -------------- gemrb/trunk/gemrb/plugins/CREImporter/CREImp.cpp gemrb/trunk/gemrb/plugins/Core/Actions.cpp gemrb/trunk/gemrb/plugins/Core/Actor.cpp gemrb/trunk/gemrb/plugins/Core/Actor.h gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp gemrb/trunk/gemrb/plugins/Core/EffectQueue.h gemrb/trunk/gemrb/plugins/Core/Inventory.cpp gemrb/trunk/gemrb/plugins/Core/Inventory.h gemrb/trunk/gemrb/plugins/Core/Spell.h gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp gemrb/trunk/gemrb/plugins/Core/Spellbook.h gemrb/trunk/gemrb/plugins/Core/Triggers.cpp gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp gemrb/trunk/gemrb/plugins/ITMImporter/ITMImp.cpp Modified: gemrb/trunk/gemrb/plugins/CREImporter/CREImp.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/CREImporter/CREImp.cpp 2007-05-06 07:19:37 UTC (rev 4641) +++ gemrb/trunk/gemrb/plugins/CREImporter/CREImp.cpp 2007-05-06 07:21:49 UTC (rev 4642) @@ -165,12 +165,12 @@ tmpDword = 0x68; //headersize TotSCEFF = 0; break; - case IE_CRE_V2_2: //iwd2 + case IE_CRE_V2_2: //iwd2 memcpy(Signature, "CHR V2.2",8); tmpDword = 0x21c; //headersize TotSCEFF = 1; break; - case IE_CRE_GEMRB: //own format + case IE_CRE_GEMRB: //own format memcpy(Signature, "CHR V0.0",8); tmpDword = 0x1dc; //headersize (iwd2-9x8+8) TotSCEFF = 1; @@ -758,7 +758,7 @@ //i think missiles equipping effects are always //in effect, if not, then add SLOT_EFFECT_MISSILE if (slottype != SLOT_EFFECT_NONE && slottype != SLOT_EFFECT_MELEE) { - act->inventory.EquipItem( Slot ); + act->inventory.EquipItem( Slot, false ); } items[index] = NULL; continue; @@ -784,7 +784,7 @@ // -24,-23,-22,-21 - quiver ieDword Equipped; str->ReadDword( &Equipped ); - act->inventory.SetEquippedSlot( ((short)Equipped)); + act->inventory.SetEquippedSlot( (short)Equipped, false); // Reading spellbook CREKnownSpell **known_spells=(CREKnownSpell **) calloc(KnownSpellsCount, sizeof(CREKnownSpell *) ); Modified: gemrb/trunk/gemrb/plugins/Core/Actions.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-05-06 07:19:37 UTC (rev 4641) +++ gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-05-06 07:21:49 UTC (rev 4642) @@ -5175,7 +5175,7 @@ if (slot<0 || slot>=MAX_QUICKWEAPONSLOT) { return; } - scr->SetEquippedQuickSlot(slot); + scr->SetEquippedQuickSlot(slot, true); if (scr->PCStats) { scr->PCStats->QuickWeaponHeaders[slot]=(ieWord) parameters->int1Parameter; } @@ -5296,6 +5296,7 @@ return; } Actor *scr = (Actor *) Sender; + //remove previous kit stuff scr->SetBase(IE_KIT, parameters->int0Parameter); } @@ -5305,7 +5306,6 @@ return; } Actor *scr = (Actor *) Sender; -//remove previous kit stuff? scr->SetBase(IE_KIT, parameters->int0Parameter); } Modified: gemrb/trunk/gemrb/plugins/Core/Actor.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-05-06 07:19:37 UTC (rev 4641) +++ gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-05-06 07:21:49 UTC (rev 4642) @@ -429,6 +429,81 @@ SetCircle( anims->GetCircleSize(), *color, core->GroundCircles[csize][color_index], core->GroundCircles[csize][(color_index == 0) ? 3 : color_index] ); } +void ApplyClab(Actor *actor, const char *clab, int level) +{ + int tidx = core->LoadTable(clab); + TableMgr *table = core->GetTable(tidx); + if (table) { + int row = table->GetRowCount(); + for(int i=0;i<level;i++) { + for (int j=0;j<row;j++) { + const char *res = table->QueryField(j,i); + if (!memcmp(res,"AP_",3)) { + core->ApplySpell(res+2, actor, actor, 0); + } + else if (!memcmp(res,"GA_",3)) { + actor->LearnSpell(res+2, 0); + } + else if (!memcmp(res,"FA_",3)) {//iwd2 only + int x=atoi(res+3); + core->DisplayStringName(x,0xffffff,actor,0); + } + else if (!memcmp(res,"FS_",3)) {//iwd2? (song?) + int x=atoi(res+3); + core->DisplayStringName(x,0xffffff,actor,0); + } + else if (!memcmp(res,"RA_",3)) {//iwd2 + int x=atoi(res+3); + core->DisplayStringName(x,0xffffff,actor,0); + } + } + } + core->DelTable(tidx); + } +} + +#define BG2_KITMASK 0xc000ffff +#define KIT_BARBARIAN 0x40000000 +#define KIT_BASECLASS 0x4000 + +//applies a kit on the character (only bg2) +bool Actor::ApplyKit(ieDword Value) +{ + //get current unmodified level (i guess) + int level = GetXPLevel(false); + int tidx = core->LoadTable("kitlist"); + TableMgr *table = core->GetTable(tidx); + if (table) { + ieDword row; + //find row by unusability + row = table->GetRowCount(); + while (row) { + row--; + ieDword Unusability = (ieDword) atoi(table->QueryField(row, 6)); + if (Value == Unusability) { + goto found_row; + } + } + //if it wasn't found, try the bg2 kit format + if ((Value&BG2_KITMASK)==KIT_BARBARIAN) { + row = (Value>>16)&0xfff; + } + //cannot find kit + if (table->GetRowCount()>=row) { + return false; + } +found_row: + ieDword cls = (ieDword) atoi(table->QueryField(row, 7)); + if (cls!=BaseStats[IE_CLASS]) { + //cannot apply kit, because the class doesn't fit + return false; + } + const char *clab = table->QueryField(row, 4); + ApplyClab(this, clab, level); + } + return true; +} + //call this when morale or moralebreak changed void pcf_morale (Actor *actor, ieDword /*Value*/) { @@ -1996,9 +2071,28 @@ return LSR_INVALID; //not existent spell } int exp = spellbook.LearnSpell(spell); + int tmp = spell->SpellNameIdentified; + if (flags&LS_LEARN) { + core->GetTokenDictionary()->SetAt("SPECIALABILITYNAME", core->GetString(tmp)); + switch (spell->SpellType) { + case IE_SPL_INNATE: + tmp = STR_GOTABILITY; + break; + case IE_SPL_SONG: + tmp = STR_GOTSONG; + break; + default: + tmp = STR_GOTSPELL; + break; + } + } else tmp = 0; + core->FreeSpell(spell, spellname, false); if (!exp) { return LSR_INVALID; } + if (tmp) { + core->DisplayConstantStringName(tmp, 0xffffff, this); + } if (flags&LS_ADDXP) { AddExperience(exp); } @@ -2811,7 +2905,7 @@ } } */ - SetStance( nextstance ); + SetStance( nextstance ); ca->autoSwitchOnEnd = false; return true; } @@ -3067,18 +3161,13 @@ } //marks the quickslot as equipped -int Actor::SetEquippedQuickSlot(int slot) +int Actor::SetEquippedQuickSlot(int slot, bool reequip) { //creatures and such - if (!PCStats) { - if (inventory.SetEquippedSlot(slot)) { - return 0; - } - return STR_MAGICWEAPON; + if (PCStats) { + slot = PCStats->QuickWeaponSlots[slot]-inventory.GetWeaponSlot(); } - - //player characters - if (inventory.SetEquippedSlot(PCStats->QuickWeaponSlots[slot]-inventory.GetWeaponSlot())) { + if (inventory.SetEquippedSlot(slot, reequip)) { return 0; } return STR_MAGICWEAPON; @@ -3318,7 +3407,23 @@ for (int i=0;i<usecount;i++) { ieDword itemvalue = itembits[itemuse[i].which]; - ieDword stat = ResolveTableValue(itemuse[i].table, GetStat(itemuse[i].stat), itemuse[i].mcol, itemuse[i].vcol); + ieDword stat = GetStat(itemuse[i].stat); + ieDword mcol = itemuse[i].mcol; + //here comes an unavoidable hackety hack because of bg2 + //feel free to solve this logic without a goto + if (itemuse[i].stat==IE_KIT) { + if ((stat&BG2_KITMASK)==KIT_BARBARIAN) { + stat = (stat>>16)&0xfff; + if (stat) { + goto resolve_stat; + } else { + stat = KIT_BASECLASS; + } + } + } else { +resolve_stat: + stat = ResolveTableValue(itemuse[i].table, stat, mcol, itemuse[i].vcol); + } if (stat&itemvalue) { return 1; } @@ -3360,3 +3465,4 @@ //missing proficiency causes only attack penalty return 0; } + Modified: gemrb/trunk/gemrb/plugins/Core/Actor.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-05-06 07:19:37 UTC (rev 4641) +++ gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-05-06 07:21:49 UTC (rev 4642) @@ -198,6 +198,8 @@ const char* GetActorNameByID(ieDword ID); /* if Lasttarget is gone, call this */ void StopAttack(); + /* checks a weapon quick slot and resets it to fist if it is empty */ + void CheckWeaponQuickSlot(unsigned int which); public: Actor(void); ~Actor(void); @@ -336,9 +338,8 @@ void SetInTrap(ieDword tmp); /* sets some of the internal flags */ void SetRunFlags(ieDword flags); -private: - /* checks a weapon quick slot and resets it to fist if it is empty */ - void CheckWeaponQuickSlot(unsigned int which); + /* applies the kit abilities, returns false if kit is not applicable */ + bool ApplyKit(ieDword Value); public: /* calls InitQuickSlot in PCStatStruct */ void SetupQuickSlot(unsigned int which, int slot, int headerindex); @@ -433,7 +434,7 @@ /* returns which slot belongs to the quickweapon slot */ int GetQuickSlot(int slot); /* Sets equipped Quick slot */ - int SetEquippedQuickSlot(int slot); + int SetEquippedQuickSlot(int slot, bool reequip); /* Uses an item on the target or point */ bool UseItemPoint(int slot, ieDword header, Point &point, bool silent); bool UseItem(int slot, ieDword header, Scriptable *target, bool silent); Modified: gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp 2007-05-06 07:19:37 UTC (rev 4641) +++ gemrb/trunk/gemrb/plugins/Core/EffectQueue.cpp 2007-05-06 07:21:49 UTC (rev 4642) @@ -342,13 +342,15 @@ return CreateEffect(effect_reference.EffText, param1, param2, timing); } -bool EffectQueue::AddEffect(Effect* fx) +void EffectQueue::AddEffect(Effect* fx, bool insert) { Effect* new_fx = new Effect; memcpy( new_fx, fx, sizeof( Effect ) ); - effects.push_back( new_fx ); - - return true; + if (insert) { + effects.insert( effects.begin(), new_fx ); + } else { + effects.push_back( new_fx ); + } } bool EffectQueue::RemoveEffect(Effect* fx) @@ -358,6 +360,8 @@ for (std::vector< Effect* >::iterator f = effects.begin(); f != effects.end(); f++ ) { Effect* fx2 = *f; + //TODO: + //equipped effects do not have point at removal if ( (fx==fx2) || !memcmp( fx, fx2, invariant_size)) { delete fx2; effects.erase( f ); @@ -390,12 +394,12 @@ } } -bool EffectQueue::AddEffect(Effect* fx, Actor* self, Actor* pretarget, Point &dest) +int EffectQueue::AddEffect(Effect* fx, Actor* self, Actor* pretarget, Point &dest) { int i; Game *game; Map *map; - bool flg; + int flg; switch (fx->Target) { case FX_TARGET_ORIGINAL: @@ -403,7 +407,7 @@ fx->PosY=self->Pos.y; flg = self->fxqueue.ApplyEffect( self, fx, true ); if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { - self->fxqueue.AddEffect( fx ); + self->fxqueue.AddEffect( fx, flg==FX_INSERT ); } break; case FX_TARGET_SELF: @@ -411,7 +415,7 @@ fx->PosY=dest.y; flg = self->fxqueue.ApplyEffect( self, fx, true ); if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { - self->fxqueue.AddEffect( fx ); + self->fxqueue.AddEffect( fx, flg==FX_INSERT ); } break; @@ -420,7 +424,7 @@ fx->PosY=pretarget->Pos.y; flg = self->fxqueue.ApplyEffect( pretarget, fx, true ); if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { - pretarget->fxqueue.AddEffect( fx ); + pretarget->fxqueue.AddEffect( fx, flg==FX_INSERT ); } break; @@ -430,12 +434,12 @@ Actor* actor = game->GetPC( i, true ); fx->PosX=actor->Pos.x; fx->PosY=actor->Pos.y; - self->fxqueue.ApplyEffect( actor, fx, true ); + flg = self->fxqueue.ApplyEffect( actor, fx, true ); if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { - actor->fxqueue.AddEffect( fx ); + actor->fxqueue.AddEffect( fx, flg==FX_INSERT ); } } - flg = false; + flg = FX_APPLIED; break; case FX_TARGET_GLOBAL_INCL_PARTY: @@ -444,12 +448,12 @@ Actor* actor = map->GetActor( i, true ); fx->PosX=actor->Pos.x; fx->PosY=actor->Pos.y; - self->fxqueue.ApplyEffect( actor, fx, true ); + flg = self->fxqueue.ApplyEffect( actor, fx, true ); if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { - actor->fxqueue.AddEffect( fx ); + actor->fxqueue.AddEffect( fx, flg==FX_INSERT ); } } - flg = false; + flg = FX_APPLIED; break; case FX_TARGET_GLOBAL_EXCL_PARTY: @@ -458,20 +462,20 @@ Actor* actor = map->GetActor( i, false ); fx->PosX=actor->Pos.x; fx->PosY=actor->Pos.y; - self->fxqueue.ApplyEffect( actor, fx, true ); + flg = self->fxqueue.ApplyEffect( actor, fx, true ); //GetActorCount can now return all nonparty critters //if (actor->InParty) continue; if (fx->TimingMode!=FX_DURATION_JUST_EXPIRED) { - actor->fxqueue.AddEffect( fx ); + actor->fxqueue.AddEffect( fx, flg==FX_INSERT ); } } - flg = false; + flg = FX_APPLIED; break; case FX_TARGET_UNKNOWN: default: printf( "Unknown FX target type: %d\n", fx->Target); - flg = false; + flg = FX_ABORT; break; } @@ -492,7 +496,7 @@ (*f)->random_value = random_value; //if applyeffect returns true, we stop adding the future effects //this is to simulate iwd2's on the fly spell resistance - if(AddEffect(*f, Owner, target, destination)) { + if(AddEffect(*f, Owner, target, destination)==FX_ABORT) { break; } } @@ -700,16 +704,16 @@ // this happens on load time too! // returns true if the process should stop calling applyeffect anymore -bool EffectQueue::ApplyEffect(Actor* target, Effect* fx, bool first_apply) +int EffectQueue::ApplyEffect(Actor* target, Effect* fx, bool first_apply) { if (!target) { fx->TimingMode=FX_DURATION_JUST_EXPIRED; - return true; + return FX_ABORT; } //printf( "FX 0x%02x: %s(%d, %d)\n", fx->Opcode, effectnames[fx->Opcode].Name, fx->Parameter1, fx->Parameter2 ); if (fx->Opcode >= MAX_EFFECTS) { fx->TimingMode=FX_DURATION_JUST_EXPIRED; - return false; + return FX_NOT_APPLIED; } ieDword GameTime = core->GetGame()->GameTime; @@ -722,13 +726,13 @@ //the effect didn't pass the probability check if (!check_probability(fx) ) { fx->TimingMode=FX_DURATION_JUST_EXPIRED; - return false; + return FX_NOT_APPLIED; } //the effect didn't pass the target level check if (check_level(target, fx) ) { fx->TimingMode=FX_DURATION_JUST_EXPIRED; - return false; + return FX_NOT_APPLIED; } //the effect didn't pass the resistance check @@ -736,7 +740,7 @@ fx->Resistance == FX_CAN_RESIST_NO_DISPEL) { if (check_resistance(target, fx) ) { fx->TimingMode=FX_DURATION_JUST_EXPIRED; - return false; + return FX_NOT_APPLIED; } } if (NeedPrepare((ieByte) fx->TimingMode) ) { @@ -747,7 +751,7 @@ switch (IsPrepared((ieByte) fx->TimingMode) ) { case DELAYED: if (fx->Duration>GameTime) { - return false; + return FX_NOT_APPLIED; } //effect triggered fx->TimingMode=TriggeredEffect((ieByte) fx->TimingMode); @@ -773,7 +777,7 @@ } EffectFunction fn = effect_refs[fx->Opcode].Function; - bool flg = false; + int res = FX_ABORT; if (fn) { if ( effect_refs[fx->Opcode].EffText > 0 ) { char *text = core->GetString( effect_refs[fx->Opcode].EffText ); @@ -781,7 +785,7 @@ free( text ); } - int res=fn( Owner?Owner:target, target, fx ); + res=fn( Owner?Owner:target, target, fx ); //if there is no owner, we assume it is the target switch( res ) { @@ -793,6 +797,12 @@ //for example, a damage effect fx->TimingMode=FX_DURATION_JUST_EXPIRED; break; + case FX_INSERT: + //put this effect in the beginning of the queue + //all known insert effects are 'permanent' too + //that is the AC effect only + //actually, permanent effects seem to be + //inserted by the game engine too case FX_PERMANENT: //don't stick around if it was permanent //for example, a strength modifier effect @@ -801,7 +811,6 @@ } break; case FX_ABORT: - flg = true; break; default: abort(); @@ -810,7 +819,7 @@ //effect not found, it is going to be discarded fx->TimingMode=FX_DURATION_JUST_EXPIRED; } - return flg; + return res; } // looks for opcode with param2 Modified: gemrb/trunk/gemrb/plugins/Core/EffectQueue.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/EffectQueue.h 2007-05-06 07:19:37 UTC (rev 4641) +++ gemrb/trunk/gemrb/plugins/Core/EffectQueue.h 2007-05-06 07:21:49 UTC (rev 4642) @@ -21,7 +21,7 @@ /** * @file EffectQueue.h - * Declares EffectQueue class holding and processing all spell effects + * Declares EffectQueue class holding and processing all spell effects * on a single Actor * @author The GemRB Project */ @@ -39,15 +39,17 @@ /** Maximum number of different Effect opcodes */ #define MAX_EFFECTS 512 +///** if the effect returns this, stop adding any other effect */ +#define FX_ABORT 0 +/** these effects don't stick around if used as permanent, + * in that case they modify a base stat like charisma modifier */ +#define FX_PERMANENT 2 /** these effects never stick around, use them for instant effects like damage */ -#define FX_NOT_APPLIED 0 +#define FX_NOT_APPLIED 3 /** these effects always stick around when applied as permanent or duration */ #define FX_APPLIED 1 -/** these effects don't stick around if used as permanent, - * in that case they modify a base stat like charisma modifier */ -#define FX_PERMANENT 2 -///** if the effect returns this, stop adding any other effect */ -#define FX_ABORT 3 +///** insert the effect instead of push back */ +#define FX_INSERT 4 //remove level effects flags #define RL_DISPELLABLE 1 //only dispellables @@ -68,7 +70,7 @@ #define BNC_SECTYPE_DEC 0x1000 #define BNC_RESOURCE_DEC 0x2000 -// FIXME: Dice roll should be probably done just once, e.g. when equipping +// FIXME: Dice roll should be probably done just once, e.g. when equipping // the item, not each time the fx are applied // <avenger> the dice values are actually level limits, except in 3 hp modifier functions // the damage function is an instant (the other 2 functions might be tricky with random values) @@ -151,19 +153,22 @@ /** Returns Actor affected by these effects */ Actor* GetOwner() { return Owner; } + /** adds an effect to the queue, it could also insert it if flagged so + * fx should be freed by the caller + */ + void AddEffect(Effect* fx, bool insert=false); /** Adds an Effect to the queue, subject to level and other checks. - * Returns true is successful. fx is just a reference, AddEffect() + * Returns FX_ABORT is unsuccessful. fx is just a reference, AddEffect() * will malloc its own copy */ - bool AddEffect(Effect* fx); - bool AddEffect(Effect* fx, Actor* self, Actor* pretarget, Point &dest); - /** Removes first Effect matching fx from the queue. + int AddEffect(Effect* fx, Actor* self, Actor* pretarget, Point &dest); + /** Removes first Effect matching fx from the queue. * Effects are matched based on their contents */ bool RemoveEffect(Effect* fx); void AddAllEffects(Actor* target, Point &dest); void ApplyAllEffects(Actor* target); /* returns true if the process should abort applying a stack of effects */ - bool ApplyEffect(Actor* target, Effect* fx, bool first_apply); + int ApplyEffect(Actor* target, Effect* fx, bool first_apply); /* directly removes effects with specified opcode, use effect_reference when you can */ void RemoveAllEffects(ieDword opcode); /* removes all effects of a given spell */ Modified: gemrb/trunk/gemrb/plugins/Core/Inventory.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Inventory.cpp 2007-05-06 07:19:37 UTC (rev 4641) +++ gemrb/trunk/gemrb/plugins/Core/Inventory.cpp 2007-05-06 07:21:49 UTC (rev 4642) @@ -182,7 +182,7 @@ Changed = false; } -void Inventory::AddSlotEffects(CREItem* slot, int type) +void Inventory::AddSlotEffects(CREItem* slot, int type, bool reequip) { Item* itm = core->GetItem( slot->ItemResRef ); if (!itm) { @@ -190,36 +190,45 @@ return; } ItemExcl|=itm->ItemExcl; - + ieWord gradient = itm->GetWieldedGradient(); if (gradient!=0xffff) { Owner->SetBase(IE_COLORS, gradient); } - + //get the equipping effects EffectQueue *eqfx = itm->GetEffectBlock(-1); core->FreeItem( itm, slot->ItemResRef, false ); - - int cnt = eqfx->GetEffectsCount(); - for (int i = 0; i < cnt; i++) { - Effect* fx = eqfx->GetEffect(i); - fx->PosX = Owner->Pos.x; - fx->PosY = Owner->Pos.y; - - // Tweak colour effects for weapons: - // If a weapon is in the off-hand, it needs to set the off-hand palette - // If it is in the main hand, it should set the weapon palette - if (IsColorslotEffect(fx->Opcode)) { - unsigned int gradienttype = fx->Parameter2 & 0xF0; - if (type == SLOT_EFFECT_MELEE && gradienttype == 0x20) - gradienttype = 0x10; // weapon - else if (type == SLOT_EFFECT_LEFT && gradienttype == 0x10) - gradienttype = 0x20; // off-hand - fx->Parameter2 &= ~0xF0; - fx->Parameter2 |= gradienttype; + if (reequip) { + eqfx->SetOwner(Owner); + eqfx->AddAllEffects( Owner, Owner->Pos); + } else { + int cnt = eqfx->GetEffectsCount(); + for (int i = 0; i < cnt; i++) { + Effect* fx = eqfx->GetEffect(i); + fx->PosX = Owner->Pos.x; + fx->PosY = Owner->Pos.y; + + // Tweak colour effects for weapons: + // If a weapon is in the off-hand, it needs to set the off-hand palette + // If it is in the main hand, it should set the weapon palette + // TODO: move this code into the effects + if (IsColorslotEffect(fx->Opcode)) { + unsigned int gradienttype = fx->Parameter2 & 0xF0; + if (type == SLOT_EFFECT_MELEE && gradienttype == 0x20) + gradienttype = 0x10; // weapon + else if (type == SLOT_EFFECT_LEFT && gradienttype == 0x10) + gradienttype = 0x20; // off-hand + fx->Parameter2 &= ~0xF0; + fx->Parameter2 |= gradienttype; + } + + if (reequip) { + //Owner->fxqueue.AddEffect( fx, Owner, Owner, Owner->Pos); + } else { + Owner->fxqueue.AddEffect( fx, false ); + } } - - Owner->fxqueue.AddEffect( fx ); } delete eqfx; core->GetGUIScriptEngine()->RunFunction("UpdateAnimation", false); @@ -500,7 +509,7 @@ item->Flags |= IE_INV_ITEM_ACQUIRED; Slots[slot] = item; Changed = true; - EquipItem(slot); + EquipItem(slot, true); return ASI_SUCCESS; } @@ -520,7 +529,7 @@ myslot->Usages[0] = (ieWord) (myslot->Usages[0] + chunk); item->Usages[0] = (ieWord) (item->Usages[0] - chunk); Changed = true; - EquipItem(slot); + EquipItem(slot, true); if (item->Usages[0] == 0) { delete item; return ASI_SUCCESS; @@ -749,7 +758,7 @@ //this is the low level equipping //all checks have been made previously -bool Inventory::EquipItem(unsigned int slot) +bool Inventory::EquipItem(unsigned int slot, bool reequip) { ITMExtHeader *header; @@ -792,12 +801,10 @@ header = itm->GetWeaponHeader(false); } if (header) { - if (slot == IW_NO_EQUIPPED) { - SetEquippedSlot(IW_NO_EQUIPPED); - } else { + if (slot != IW_NO_EQUIPPED) { Owner->SetupQuickSlot(ACT_WEAPON1+weaponslot, slot+SLOT_MELEE, 0); - SetEquippedSlot(slot); } + SetEquippedSlot(slot, true); effect = 0; // SetEquippedSlot will already call AddSlotEffects UpdateWeaponAnimation(); } @@ -808,7 +815,7 @@ weaponslot = FindTypedRangedWeapon(header->ProjectileQualifier); if (weaponslot != SLOT_FIST) { weaponslot -= SLOT_MELEE; - SetEquippedSlot(slot-SLOT_MELEE); + SetEquippedSlot(slot-SLOT_MELEE, true); Owner->SetupQuickSlot(ACT_WEAPON1+weaponslot, slot, 0); } } @@ -833,7 +840,7 @@ if (item->Flags & IE_INV_ITEM_CURSED) { item->Flags|=IE_INV_ITEM_UNDROPPABLE; } - AddSlotEffects( item, effect ); + AddSlotEffects( item, effect, reequip ); } core->FreeItem(itm, item->ItemResRef, false); return true; @@ -1046,7 +1053,7 @@ return Equipped+SLOT_MELEE; } -bool Inventory::SetEquippedSlot(int slotcode) +bool Inventory::SetEquippedSlot(int slotcode, bool reequip) { if (Equipped != IW_NO_EQUIPPED) { RemoveSlotEffects( GetSlotItem(SLOT_MELEE+Equipped) ); @@ -1076,7 +1083,7 @@ if (item->Flags & IE_INV_ITEM_CURSED) { item->Flags|=IE_INV_ITEM_UNDROPPABLE; } - AddSlotEffects( item, effects ); + AddSlotEffects( item, effects, reequip ); } UpdateWeaponAnimation(); return true; @@ -1278,7 +1285,7 @@ } } - SetEquippedSlot(best_slot); + SetEquippedSlot(best_slot, true); UpdateWeaponAnimation(); } Modified: gemrb/trunk/gemrb/plugins/Core/Inventory.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Inventory.h 2007-05-06 07:19:37 UTC (rev 4641) +++ gemrb/trunk/gemrb/plugins/Core/Inventory.h 2007-05-06 07:21:49 UTC (rev 4642) @@ -267,19 +267,19 @@ int FindItem(const char *resref, unsigned int flags); bool DropItemAtLocation(unsigned int slot, unsigned int flags, Map *map, Point &loc); bool DropItemAtLocation(const char *resref, unsigned int flags, Map *map, Point &loc); - bool SetEquippedSlot(int slotcode); + bool SetEquippedSlot(int slotcode, bool reequip); int GetEquipped(); //right hand int GetEquippedSlot(); //left hand int GetShieldSlot(); - void AddSlotEffects( CREItem* slot, int type ); + void AddSlotEffects( CREItem* slot, int type, bool reequip ); //void AddAllEffects(); /** Returns item in specified slot. Does NOT change inventory */ CREItem* GetSlotItem(unsigned int slot); bool ChangeItemFlag(unsigned int slot, ieDword value, int mode); /** Equips the item, don't use it directly for weapons */ - bool EquipItem(unsigned int slot); + bool EquipItem(unsigned int slot, bool reequip); bool UnEquipItem(unsigned int slot, bool removecurse); /** Returns equipped weapon */ CREItem *GetUsedWeapon(bool leftorright); Modified: gemrb/trunk/gemrb/plugins/Core/Spell.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spell.h 2007-05-06 07:19:37 UTC (rev 4641) +++ gemrb/trunk/gemrb/plugins/Core/Spell.h 2007-05-06 07:21:49 UTC (rev 4642) @@ -59,6 +59,17 @@ //this is a relocated bit (used in iwd2 as 0x4000) #define SF_SIMPLIFIED_DURATION 0x40 +//spelltypes in spells +#define IE_SPL_ITEM 0 +#define IE_SPL_WIZARD 1 +#define IE_SPL_PRIEST 2 +#define IE_SPL_PSION 3 +#define IE_SPL_INNATE 4 +#define IE_SPL_SONG 5 + +//this is not the same as the book types which is 3 or 11) +#define NUM_SPELL_TYPES 6 + /** * @class SPLExtHeader * Header for Spell special effects Modified: gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp 2007-05-06 07:19:37 UTC (rev 4641) +++ gemrb/trunk/gemrb/plugins/Core/Spellbook.cpp 2007-05-06 07:21:49 UTC (rev 4642) @@ -32,16 +32,16 @@ static ieResRef *shapelist = NULL; static bool SBInitialized = false; -static int NUM_SPELL_TYPES = 3; +static int NUM_BOOK_TYPES = 3; static bool IWD2Style = false; -//spelltypes in all games except iwd2 -#define IE_SPL_WIZARD 1 -#define IE_SPL_PRIEST 2 -#define IE_SPL_INNATE 4 +//spell header-->spell book type conversion (iwd2 is different) +static int spelltypes[NUM_SPELL_TYPES]={ + IE_SPELL_TYPE_INNATE, IE_SPELL_TYPE_WIZARD, + IE_SPELL_TYPE_PRIEST, IE_SPELL_TYPE_WIZARD, IE_SPELL_TYPE_INNATE, + IE_SPELL_TYPE_SONG +}; -static int spelltypes[3]={IE_SPL_PRIEST,IE_SPL_WIZARD,IE_SPL_INNATE}; - /* temporarily out static ieResRef *ResolveSpellName(ieDword index) { @@ -96,7 +96,7 @@ if (!SBInitialized) { InitializeSpellbook(); } - spells = new std::vector<CRESpellMemorization*> [NUM_SPELL_TYPES]; + spells = new std::vector<CRESpellMemorization*> [NUM_BOOK_TYPES]; } void Spellbook::InitializeSpellbook() @@ -108,9 +108,9 @@ innatelist = GetSpellTable("listinnt",0); songlist = GetSpellTable("listsong",0); shapelist = GetSpellTable("listshap",0); - NUM_SPELL_TYPES=NUM_IWD2_SPELLTYPES; //iwd2 spell types + NUM_BOOK_TYPES=NUM_IWD2_SPELLTYPES; //iwd2 spell types } else { - NUM_SPELL_TYPES=NUM_SPELLTYPES; //bg/pst/iwd1 spell types + NUM_BOOK_TYPES=NUM_SPELLTYPES; //bg/pst/iwd1 spell types } } return; @@ -135,7 +135,7 @@ Spellbook::~Spellbook() { - for (int i = 0; i < NUM_SPELL_TYPES; i++) { + for (int i = 0; i < NUM_BOOK_TYPES; i++) { for (unsigned int j = 0; j < spells[i].size(); j++) { if (spells[i][j]) { FreeSpellPage( spells[i][j] ); @@ -193,7 +193,7 @@ //if resref=="" then it is a haveanyspell bool Spellbook::HaveSpell(const char *resref, ieDword flags) { - for (int i = 0; i < NUM_SPELL_TYPES; i++) { + for (int i = 0; i < NUM_BOOK_TYPES; i++) { for (unsigned int j = 0; j < spells[i].size(); j++) { CRESpellMemorization* sm = spells[i][j]; for (unsigned int k = 0; k < sm->memorized_spells.size(); k++) { @@ -215,7 +215,7 @@ int Spellbook::GetTypes() const { - return NUM_SPELL_TYPES; + return NUM_BOOK_TYPES; } bool Spellbook::IsIWDSpellBook() const @@ -231,7 +231,7 @@ unsigned int Spellbook::GetTotalPageCount() const { unsigned int total = 0; - for(int type =0; type<NUM_SPELL_TYPES; type++) { + for(int type =0; type<NUM_BOOK_TYPES; type++) { total += GetSpellLevelCount(type); } return total; @@ -240,7 +240,7 @@ unsigned int Spellbook::GetTotalKnownSpellsCount() const { unsigned int total = 0; - for(int type =0; type<NUM_SPELL_TYPES; type++) { + for(int type =0; type<NUM_BOOK_TYPES; type++) { unsigned int level = GetSpellLevelCount(type); while(level--) { total += GetKnownSpellsCount(type, level); @@ -252,7 +252,7 @@ unsigned int Spellbook::GetTotalMemorizedSpellsCount() const { unsigned int total = 0; - for(int type =0; type<NUM_SPELL_TYPES; type++) { + for(int type =0; type<NUM_BOOK_TYPES; type++) { unsigned int level = GetSpellLevelCount(type); while(level--) { total += GetMemorizedSpellsCount(type, level); @@ -263,7 +263,7 @@ unsigned int Spellbook::GetKnownSpellsCount(int type, unsigned int level) const { - if (type >= NUM_SPELL_TYPES || level >= GetSpellLevelCount(type)) + if (type >= NUM_BOOK_TYPES || level >= GetSpellLevelCount(type)) return 0; return (unsigned int) spells[type][level]->known_spells.size(); } @@ -282,20 +282,20 @@ 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++) { + for (int i = 0; i < NUM_BOOK_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); @@ -322,11 +322,11 @@ std::vector< CRESpellMemorization* >::iterator sm; for (sm = spells[type].begin(); sm != spells[type].end(); sm++) { std::vector< CREKnownSpell* >::iterator ks; - + 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); @@ -340,7 +340,7 @@ //removes spell from both memorized/book void Spellbook::RemoveSpell(ieResRef ResRef) { - for(int type =0; type<NUM_SPELL_TYPES; type++) { + for(int type =0; type<NUM_BOOK_TYPES; type++) { std::vector< CRESpellMemorization* >::iterator sm; for (sm = spells[type].begin(); sm != spells[type].end(); sm++) { std::vector< CREKnownSpell* >::iterator ks; @@ -358,12 +358,19 @@ } } +//returns the page group of the spellbook this spelltype belongs to +//psionics are stored in the mage spell list +//wizard/priest are trivial +//songs are stored elsewhere +//wildshapes are marked as innate, they need some hack to get stored +//in the right group +//the rest are stored as innate int Spellbook::GetSpellType(int spelltype) { if (IWD2Style) return spelltype; - for(int i=0;i<3;i++) { - if (spelltypes[i]==spelltype) return i; + if (spelltype<6) { + return spelltypes[spelltype]; } return IE_SPELL_TYPE_INNATE; } @@ -388,7 +395,7 @@ bool Spellbook::AddKnownSpell(int type, unsigned int level, CREKnownSpell *spl) { - if (type >= NUM_SPELL_TYPES) { + if (type >= NUM_BOOK_TYPES) { return false; } if ( level >= GetSpellLevelCount(type) ) { @@ -407,7 +414,7 @@ CREKnownSpell* Spellbook::GetKnownSpell(int type, unsigned int level, unsigned int index) const { - if (type >= NUM_SPELL_TYPES || level >= GetSpellLevelCount(type) || index >= spells[type][level]->known_spells.size()) + if (type >= NUM_BOOK_TYPES || level >= GetSpellLevelCount(type) || index >= spells[type][level]->known_spells.size()) return NULL; return spells[type][level]->known_spells[index]; } @@ -424,7 +431,7 @@ unsigned int Spellbook::GetMemorizedSpellsCount(int type, unsigned int level) const { - if (type >= NUM_SPELL_TYPES) + if (type >= NUM_BOOK_TYPES) return 0; if(level >= GetSpellLevelCount(type)) return 0; @@ -433,7 +440,7 @@ CREMemorizedSpell* Spellbook::GetMemorizedSpell(int type, unsigned int level, unsigned int index) const { - if (type >= NUM_SPELL_TYPES || level >= GetSpellLevelCount(type) || index >= spells[type][level]->memorized_spells.size()) + if (type >= NUM_BOOK_TYPES || level >= GetSpellLevelCount(type) || index >= spells[type][level]->memorized_spells.size()) return NULL; return spells[type][level]->memorized_spells[index]; } @@ -441,7 +448,7 @@ //creates a spellbook level bool Spellbook::AddSpellMemorization(CRESpellMemorization* sm) { - if (sm->Type>=NUM_SPELL_TYPES) { + if (sm->Type>=NUM_BOOK_TYPES) { return false; } std::vector<CRESpellMemorization*>* s = &spells[sm->Type]; @@ -480,7 +487,7 @@ { int type; - for(type=0;type<NUM_SPELL_TYPES;type++) { + for(type=0;type<NUM_BOOK_TYPES;type++) { for(int level = GetSpellLevelCount(type); level--;) { CRESpellMemorization* sm = spells[type][level]; sm->Number2=sm->Number; @@ -496,7 +503,7 @@ { int diff; - if (type >= NUM_SPELL_TYPES) { + if (type >= NUM_BOOK_TYPES) { return; } if ( level >= GetSpellLevelCount(type) ) { @@ -525,7 +532,7 @@ int Spellbook::GetMemorizableSpellsCount(int type, unsigned int level, bool bonus) const { - if (type >= NUM_SPELL_TYPES || level >= GetSpellLevelCount(type)) + if (type >= NUM_BOOK_TYPES || level >= GetSpellLevelCount(type)) return 0; CRESpellMemorization* sm = spells[type][level]; if (bonus) @@ -550,7 +557,7 @@ bool Spellbook::UnmemorizeSpell(CREMemorizedSpell* spell) { - for (int i = 0; i < NUM_SPELL_TYPES; i++) { + for (int i = 0; i < NUM_BOOK_TYPES; i++) { std::vector< CRESpellMemorization* >::iterator sm; for (sm = spells[i].begin(); sm != spells[i].end(); sm++) { std::vector< CREMemorizedSpell* >::iterator s; @@ -574,7 +581,7 @@ { int mask=1; - for (int i = 0; i < NUM_SPELL_TYPES; i++) { + for (int i = 0; i < NUM_BOOK_TYPES; i++) { if (type&mask) { mask<<=1; continue; @@ -599,7 +606,7 @@ void Spellbook::ChargeAllSpells() { - for (int i = 0; i < NUM_SPELL_TYPES; i++) { + for (int i = 0; i < NUM_BOOK_TYPES; i++) { for (unsigned int j = 0; j < spells[i].size(); j++) { CRESpellMemorization* sm = spells[i][j]; @@ -613,7 +620,7 @@ //returns true if successful bool Spellbook::DepleteSpell(int type) { - if (type>=NUM_SPELL_TYPES) { + if (type>=NUM_BOOK_TYPES) { return false; } size_t j = GetSpellLevelCount(type); @@ -631,7 +638,7 @@ bool Spellbook::DepleteSpell(int type, unsigned int page, unsigned int slot) { - if (NUM_SPELL_TYPES<=type) { + if (NUM_BOOK_TYPES<=type) { return false; } if (spells[type].size()<=page) { @@ -669,12 +676,12 @@ { int pos = 0; int actual = 0; - + memset(array, 0, count * sizeof(SpellExtHeader) ); - for (int i = 0; i < NUM_SPELL_TYPES; i++) { + for (int i = 0; i < NUM_BOOK_TYPES; i++) { for (unsigned int j = 0; j < spells[i].size(); j++) { CRESpellMemorization* sm = spells[i][j]; - + if ( !(type & (1<<sm->Type)) ) { continue; } @@ -695,7 +702,7 @@ count--; memcpy(array[pos].spellname, slot->SpellResRef, sizeof(ieResRef) ); int ehc; - + for(ehc=0;ehc<spl->ExtHeaderCount-1;ehc++) { if (level<spl->ext_headers[ehc+1].RequiredLevel) { break; @@ -782,8 +789,8 @@ { size_t i = spellinfo.size(); while(i--) { - if( (spellinfo[i]->level==level) && - (spellinfo[i]->type==type) && + if( (spellinfo[i]->level==level) && + (spellinfo[i]->type==type) && !strnicmp(spellinfo[i]->spellname, spellname, 8)) { return spellinfo[i]; } @@ -795,7 +802,7 @@ void Spellbook::GenerateSpellInfo() { ClearSpellInfo(); //just in case - for (int i = 0; i < NUM_SPELL_TYPES; i++) { + for (int i = 0; i < NUM_BOOK_TYPES; i++) { for (unsigned int j = 0; j < spells[i].size(); j++) { CRESpellMemorization* sm = spells[i][j]; @@ -817,7 +824,7 @@ memcpy(seh->spellname, slot->SpellResRef, sizeof(ieResRef) ); int ehc; - + for(ehc=0;ehc<spl->ExtHeaderCount-1;ehc++) { if (level<spl->ext_headers[ehc+1].RequiredLevel) { break; @@ -848,7 +855,7 @@ unsigned int k; printf( "SPELLBOOK:\n" ); - for (int i = 0; i < NUM_SPELL_TYPES; i++) { + for (int i = 0; i < NUM_BOOK_TYPES; i++) { for (unsigned int j = 0; j < spells[i].size(); j++) { CRESpellMemorization* sm = spells[i][j]; //if (!sm || !sm->Number) continue; @@ -858,7 +865,7 @@ //printf ( "type: %d: L: %d; N1: %d; N2: %d; T: %d; KC: %d; MC: %d\n", i, // sm->Level, sm->Number, sm->Number2, sm->Type, (int) sm->known_spells.size(), (int) sm->memorized_spells.size() ); - if (sm->known_spells.size()) + if (sm->known_spells.size()) printf( " Known spells:\n" ); for (k = 0; k < sm->known_spells.size(); k++) { CREKnownSpell* spl = sm->known_spells[k]; @@ -867,7 +874,7 @@ printf ( " %2d: %8s L: %d T: %d\n", k, spl->SpellResRef, spl->Level, spl->Type ); } - if (sm->memorized_spells.size()) + if (sm->memorized_spells.size()) printf( " Memorized spells:\n" ); for (k = 0; k < sm->memorized_spells.size (); k++) { CREMemorizedSpell* spl = sm->memorized_spells[k]; Modified: gemrb/trunk/gemrb/plugins/Core/Spellbook.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Spellbook.h 2007-05-06 07:19:37 UTC (rev 4641) +++ gemrb/trunk/gemrb/plugins/Core/Spellbook.h 2007-05-06 07:21:49 UTC (rev 4642) @@ -54,9 +54,9 @@ #define HS_DEPLETE 1 //LearnSpell flags -#define LS_ADDXP 1 -#define LS_LEARN 2 -#define LS_STATS 4 +#define LS_ADDXP 1 //give xp for learning it +#define LS_LEARN 2 //give message when learned it +#define LS_STATS 4 //check stats (alignment, etc) //LearnSpell return values #define LSR_OK 0 @@ -71,7 +71,8 @@ typedef enum ieSpellType { IE_SPELL_TYPE_PRIEST = 0, IE_SPELL_TYPE_WIZARD = 1, - IE_SPELL_TYPE_INNATE = 2 + IE_SPELL_TYPE_INNATE = 2, + IE_SPELL_TYPE_SONG = 3 //not in spellbook } ieSpellType; #define NUM_SPELLTYPES 3 Modified: gemrb/trunk/gemrb/plugins/Core/Triggers.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Triggers.cpp 2007-05-06 07:19:37 UTC (rev 4641) +++ gemrb/trunk/gemrb/plugins/Core/Triggers.cpp 2007-05-06 07:21:49 UTC (rev 4642) @@ -357,9 +357,18 @@ } Actor* actor = (Actor *) scr; - if ( actor->GetStat(IE_KIT) == (ieDword) parameters->int0Parameter) { + ieDword kit = actor->GetStat(IE_KIT); + //TODO: fix baseclass / barbarian confusion + + //IWD2 style kit matching (also used for mage schools) + if (kit == (ieDword) (parameters->int0Parameter)) { return 1; } + //BG2 style kit matching + kit = (kit>>16)|(kit<<16); + if ( kit == (ieDword) (parameters->int0Parameter)) { + return 1; + } return 0; } Modified: gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-05-06 07:19:37 UTC (rev 4641) +++ gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-05-06 07:21:49 UTC (rev 4642) @@ -763,6 +763,20 @@ return FX_PERMANENT; } + // FIXME: set to Param1 or Param1-1 ? + if (type == 16) { + if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { + if (BASE_GET( IE_ARMORCLASS) > fx->Parameter1) { + BASE_SET( IE_ARMORCLASS, fx->Parameter1 ); + } + } else { + if (STAT_GET( IE_ARMORCLASS) > fx->Parameter1) { + STAT_SET( IE_ARMORCLASS, fx->Parameter1 ); + } + } + return FX_INSERT; + } + //the original engine did work with the combination of these bits //but since it crashed, we are not bound to the same rules if (type & 1) { @@ -778,18 +792,6 @@ HandleBonus(target, IE_ACSLASHINGMOD, fx->Parameter1, fx->TimingMode); } - // FIXME: set to Param1 or Param1-1 ? - if (type == 16) { - if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { - if (BASE_GET( IE_ARMORCLASS) > fx->Parameter1) { - BASE_SET( IE_ARMORCLASS, fx->Parameter1 ); - } - } else { - if (STAT_GET( IE_ARMORCLASS) > fx->Parameter1) { - STAT_SET( IE_ARMORCLASS, fx->Parameter1 ); - } - } - } return FX_PERMANENT; } @@ -2461,7 +2463,7 @@ int fx_equip_item (Actor* /*Owner*/, Actor* target, Effect* fx) { if (core->QuerySlotEffects( fx->Parameter2 )) { - target->inventory.EquipItem(fx->Parameter2); + target->inventory.EquipItem(fx->Parameter2, true); } target->ReinitQuickSlots(); return FX_NOT_APPLIED; Modified: gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-05-06 07:19:37 UTC (rev 4641) +++ gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-05-06 07:21:49 UTC (rev 4642) @@ -6426,7 +6426,7 @@ // Note: this forcefully gets rid of any item currently // in the slot without properly unequipping it actor->inventory.SetSlotItemRes( ItemResRef, SlotID, Charge0, Charge1, Charge2 ); - actor->inventory.EquipItem(SlotID); + actor->inventory.EquipItem(SlotID, true); actor->RefreshEffects(); actor->ReinitQuickSlots(); } @@ -7392,7 +7392,7 @@ return RuntimeError( "Actor not found" ); } - int ret = actor->SetEquippedQuickSlot(slot); + int ret = actor->SetEquippedQuickSlot(slot, true); return PyInt_FromLong( ret ); } Modified: gemrb/trunk/gemrb/plugins/ITMImporter/ITMImp.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/ITMImporter/ITMImp.cpp 2007-05-06 07:19:37 UTC (rev 4641) +++ gemrb/trunk/gemrb/plugins/ITMImporter/ITMImp.cpp 2007-05-06 07:21:49 UTC (rev 4642) @@ -96,7 +96,7 @@ str->Read( &k3,1 ); str->Read( &s->MinWisdom,1 ); str->Read( &k4,1 ); - s->KitUsability=(k1<<24) | (k2<<16) | (k3<<8) | k1; //bg2/iwd2 specific + s->KitUsability=(k1<<24) | (k2<<16) | (k3<<8) | k4; //bg2/iwd2 specific str->Read( &s->MinConstitution,1 ); str->Read( &s->WeaProf,1 ); //bg2 specific str->Read( &s->MinCharisma,1 ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-05-06 10:19:34
|
Revision: 4644 http://gemrb.svn.sourceforge.net/gemrb/?rev=4644&view=rev Author: avenger_teambg Date: 2007-05-06 03:19:32 -0700 (Sun, 06 May 2007) Log Message: ----------- don't compare target point when removing effects initialize target point when loading V1 effects Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Effect.h gemrb/trunk/gemrb/plugins/EFFImporter/EFFImp.cpp Modified: gemrb/trunk/gemrb/plugins/Core/Effect.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Effect.h 2007-05-06 08:12:17 UTC (rev 4643) +++ gemrb/trunk/gemrb/plugins/Core/Effect.h 2007-05-06 10:19:32 UTC (rev 4644) @@ -104,9 +104,10 @@ ieResRef Source; ieDword SecondaryType; ieDword SecondaryDelay; //still not sure about this - ieDword PosX, PosY; // These are not in the IE files, but are our precomputed values ieDword random_value; + // These could be in the effv2.0 fields, but not used in comparison + ieDword PosX, PosY; }; // FIXME: what about area spells? They can have map & coordinates as target Modified: gemrb/trunk/gemrb/plugins/EFFImporter/EFFImp.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/EFFImporter/EFFImp.cpp 2007-05-06 08:12:17 UTC (rev 4643) +++ gemrb/trunk/gemrb/plugins/EFFImporter/EFFImp.cpp 2007-05-06 10:19:32 UTC (rev 4644) @@ -100,7 +100,10 @@ str->ReadDword( &fx->SavingThrowType ); str->ReadDword( &fx->SavingThrowBonus ); str->ReadWord( &fx->IsVariable ); - str->ReadWord( &fx->IsSaveForHalfDamage ); + str->ReadWord( &fx->IsSaveForHalfDamage ); + + fx->PosX=0xffffffff; + fx->PosY=0xffffffff; return fx; } @@ -149,5 +152,11 @@ str->ReadDword( &fx->SecondaryType ); str->Seek( 60, GEM_CURRENT_POS ); + //FIXME: + //actually the effect positions are saved somewhere + //and there is a position for source and target too + //if Pos is only a word, consider using a point + fx->PosX=0xffffffff; + fx->PosY=0xffffffff; return fx; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-05-07 21:15:27
|
Revision: 4647 http://gemrb.svn.sourceforge.net/gemrb/?rev=4647&view=rev Author: avenger_teambg Date: 2007-05-07 14:15:26 -0700 (Mon, 07 May 2007) Log Message: ----------- rolled back equipping flag delay equipping items after actor gets area (and game object) Modified Paths: -------------- gemrb/trunk/gemrb/plugins/CREImporter/CREImp.cpp gemrb/trunk/gemrb/plugins/Core/Actions.cpp gemrb/trunk/gemrb/plugins/Core/Actor.cpp gemrb/trunk/gemrb/plugins/Core/Actor.h gemrb/trunk/gemrb/plugins/Core/Inventory.cpp gemrb/trunk/gemrb/plugins/Core/Inventory.h gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp Modified: gemrb/trunk/gemrb/plugins/CREImporter/CREImp.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/CREImporter/CREImp.cpp 2007-05-06 20:16:02 UTC (rev 4646) +++ gemrb/trunk/gemrb/plugins/CREImporter/CREImp.cpp 2007-05-07 21:15:26 UTC (rev 4647) @@ -753,13 +753,16 @@ CREItem *item = items[index]; if (item && core->Exists(item->ItemResRef, IE_ITM_CLASS_ID)) { act->inventory.SetSlotItem( item, Slot ); + /* this stuff will be done in Actor::SetMap + * after the actor gets an area (and game obj) int slottype = core->QuerySlotEffects( Slot ); //weapons will be equipped differently, see SetEquippedSlot later //i think missiles equipping effects are always //in effect, if not, then add SLOT_EFFECT_MISSILE if (slottype != SLOT_EFFECT_NONE && slottype != SLOT_EFFECT_MELEE) { - act->inventory.EquipItem( Slot, false ); + act->inventory.EquipItem( Slot, true ); } + */ items[index] = NULL; continue; } @@ -782,9 +785,10 @@ // 0,1,2,3 - weapon slots // 1000 - fist // -24,-23,-22,-21 - quiver - ieDword Equipped; - str->ReadDword( &Equipped ); - act->inventory.SetEquippedSlot( (short)Equipped, false); + //the equipping effects are delayed until the actor gets an area + //ieDword Equipped; + str->ReadDword( &act->Equipped ); + //act->inventory.SetEquippedSlot( (short)Equipped, true); // Reading spellbook CREKnownSpell **known_spells=(CREKnownSpell **) calloc(KnownSpellsCount, sizeof(CREKnownSpell *) ); Modified: gemrb/trunk/gemrb/plugins/Core/Actions.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-05-06 20:16:02 UTC (rev 4646) +++ gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2007-05-07 21:15:26 UTC (rev 4647) @@ -3555,6 +3555,8 @@ if (slot<0) { return; } + actor->inventory.EquipItem(slot); + actor->ReinitQuickSlots(); } //iwd2 also has a flag for unequip (it might collide with original!) @@ -3570,9 +3572,16 @@ } if (parameters->int0Parameter==0) { //unequip //move item to inventory if possible + if (actor->inventory.UnEquipItem(slot, true)) { + CREItem *si = actor->inventory.RemoveItem(slot); + actor->inventory.AddSlotItem(si, -1); + } } else { //equip //equip item if possible + /// + actor->inventory.EquipItem(slot); } + actor->ReinitQuickSlots(); } void GameScript::DropItem(Scriptable *Sender, Action* parameters) @@ -5175,7 +5184,7 @@ if (slot<0 || slot>=MAX_QUICKWEAPONSLOT) { return; } - scr->SetEquippedQuickSlot(slot, true); + scr->SetEquippedQuickSlot(slot); if (scr->PCStats) { scr->PCStats->QuickWeaponHeaders[slot]=(ieWord) parameters->int1Parameter; } Modified: gemrb/trunk/gemrb/plugins/Core/Actor.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-05-06 20:16:02 UTC (rev 4646) +++ gemrb/trunk/gemrb/plugins/Core/Actor.cpp 2007-05-07 21:15:26 UTC (rev 4647) @@ -1565,9 +1565,31 @@ void Actor::SetMap(Map *map, ieWord LID, ieWord GID) { + bool effinit=false; + if (!GetCurrentArea()) { + effinit = true; + } Scriptable::SetMap(map); localID = LID; globalID = GID; + + //this hack is to delay the equipping effects until the actor has + //an area (and the game object is also existing) + if (effinit) { + int SlotCount = inventory.GetSlotCount(); + for (int Slot = 0; Slot<SlotCount;Slot++) { + int slottype = core->QuerySlotEffects( Slot ); + switch (slottype) { + case SLOT_EFFECT_NONE: + case SLOT_EFFECT_MELEE: + break; + default: + inventory.EquipItem( Slot ); + break; + } + } + } + inventory.SetEquippedSlot( Equipped ); } void Actor::SetPosition(Point &position, int jump, int radius) @@ -3161,13 +3183,13 @@ } //marks the quickslot as equipped -int Actor::SetEquippedQuickSlot(int slot, bool reequip) +int Actor::SetEquippedQuickSlot(int slot) { //creatures and such if (PCStats) { slot = PCStats->QuickWeaponSlots[slot]-inventory.GetWeaponSlot(); } - if (inventory.SetEquippedSlot(slot, reequip)) { + if (inventory.SetEquippedSlot(slot)) { return 0; } return STR_MAGICWEAPON; Modified: gemrb/trunk/gemrb/plugins/Core/Actor.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-05-06 20:16:02 UTC (rev 4646) +++ gemrb/trunk/gemrb/plugins/Core/Actor.h 2007-05-07 21:15:26 UTC (rev 4647) @@ -133,6 +133,7 @@ ieVariable KillVar; //this second field is present in pst and iwd1 Inventory inventory; + ieDword Equipped; //i found no better place for this :( Spellbook spellbook; //savefile version (creatures embedded in area) int version; @@ -434,7 +435,7 @@ /* returns which slot belongs to the quickweapon slot */ int GetQuickSlot(int slot); /* Sets equipped Quick slot */ - int SetEquippedQuickSlot(int slot, bool reequip); + int SetEquippedQuickSlot(int slot); /* Uses an item on the target or point */ bool UseItemPoint(int slot, ieDword header, Point &point, bool silent); bool UseItem(int slot, ieDword header, Scriptable *target, bool silent); Modified: gemrb/trunk/gemrb/plugins/Core/Inventory.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Inventory.cpp 2007-05-06 20:16:02 UTC (rev 4646) +++ gemrb/trunk/gemrb/plugins/Core/Inventory.cpp 2007-05-07 21:15:26 UTC (rev 4647) @@ -182,7 +182,8 @@ Changed = false; } -void Inventory::AddSlotEffects(CREItem* slot, int type, bool reequip) +//hmm, dunno how to implement type +void Inventory::AddSlotEffects(CREItem* slot, int /*type*/) { Item* itm = core->GetItem( slot->ItemResRef ); if (!itm) { @@ -199,37 +200,8 @@ //get the equipping effects EffectQueue *eqfx = itm->GetEffectBlock(-1); core->FreeItem( itm, slot->ItemResRef, false ); - if (reequip) { - eqfx->SetOwner(Owner); - eqfx->AddAllEffects( Owner, Owner->Pos); - } else { - int cnt = eqfx->GetEffectsCount(); - for (int i = 0; i < cnt; i++) { - Effect* fx = eqfx->GetEffect(i); - fx->PosX = Owner->Pos.x; - fx->PosY = Owner->Pos.y; - - // Tweak colour effects for weapons: - // If a weapon is in the off-hand, it needs to set the off-hand palette - // If it is in the main hand, it should set the weapon palette - // TODO: move this code into the effects - if (IsColorslotEffect(fx->Opcode)) { - unsigned int gradienttype = fx->Parameter2 & 0xF0; - if (type == SLOT_EFFECT_MELEE && gradienttype == 0x20) - gradienttype = 0x10; // weapon - else if (type == SLOT_EFFECT_LEFT && gradienttype == 0x10) - gradienttype = 0x20; // off-hand - fx->Parameter2 &= ~0xF0; - fx->Parameter2 |= gradienttype; - } - - if (reequip) { - //Owner->fxqueue.AddEffect( fx, Owner, Owner, Owner->Pos); - } else { - Owner->fxqueue.AddEffect( fx, false ); - } - } - } + eqfx->SetOwner(Owner); + eqfx->AddAllEffects( Owner, Owner->Pos); delete eqfx; core->GetGUIScriptEngine()->RunFunction("UpdateAnimation", false); } @@ -509,7 +481,7 @@ item->Flags |= IE_INV_ITEM_ACQUIRED; Slots[slot] = item; Changed = true; - EquipItem(slot, true); + EquipItem(slot); return ASI_SUCCESS; } @@ -529,7 +501,7 @@ myslot->Usages[0] = (ieWord) (myslot->Usages[0] + chunk); item->Usages[0] = (ieWord) (item->Usages[0] - chunk); Changed = true; - EquipItem(slot, true); + EquipItem(slot); if (item->Usages[0] == 0) { delete item; return ASI_SUCCESS; @@ -758,7 +730,7 @@ //this is the low level equipping //all checks have been made previously -bool Inventory::EquipItem(unsigned int slot, bool reequip) +bool Inventory::EquipItem(unsigned int slot) { ITMExtHeader *header; @@ -804,7 +776,7 @@ if (slot != IW_NO_EQUIPPED) { Owner->SetupQuickSlot(ACT_WEAPON1+weaponslot, slot+SLOT_MELEE, 0); } - SetEquippedSlot(slot, true); + SetEquippedSlot(slot); effect = 0; // SetEquippedSlot will already call AddSlotEffects UpdateWeaponAnimation(); } @@ -815,7 +787,7 @@ weaponslot = FindTypedRangedWeapon(header->ProjectileQualifier); if (weaponslot != SLOT_FIST) { weaponslot -= SLOT_MELEE; - SetEquippedSlot(slot-SLOT_MELEE, true); + SetEquippedSlot(slot-SLOT_MELEE); Owner->SetupQuickSlot(ACT_WEAPON1+weaponslot, slot, 0); } } @@ -840,7 +812,7 @@ if (item->Flags & IE_INV_ITEM_CURSED) { item->Flags|=IE_INV_ITEM_UNDROPPABLE; } - AddSlotEffects( item, effect, reequip ); + AddSlotEffects( item, effect ); } core->FreeItem(itm, item->ItemResRef, false); return true; @@ -1053,7 +1025,7 @@ return Equipped+SLOT_MELEE; } -bool Inventory::SetEquippedSlot(int slotcode, bool reequip) +bool Inventory::SetEquippedSlot(int slotcode) { if (Equipped != IW_NO_EQUIPPED) { RemoveSlotEffects( GetSlotItem(SLOT_MELEE+Equipped) ); @@ -1083,7 +1055,7 @@ if (item->Flags & IE_INV_ITEM_CURSED) { item->Flags|=IE_INV_ITEM_UNDROPPABLE; } - AddSlotEffects( item, effects, reequip ); + AddSlotEffects( item, effects); } UpdateWeaponAnimation(); return true; @@ -1285,7 +1257,7 @@ } } - SetEquippedSlot(best_slot, true); + SetEquippedSlot(best_slot); UpdateWeaponAnimation(); } Modified: gemrb/trunk/gemrb/plugins/Core/Inventory.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Inventory.h 2007-05-06 20:16:02 UTC (rev 4646) +++ gemrb/trunk/gemrb/plugins/Core/Inventory.h 2007-05-07 21:15:26 UTC (rev 4647) @@ -229,7 +229,7 @@ void SetOwner(Actor* act) { Owner = act; }; /** returns number of all slots in the inventory */ - int GetSlotCount() { return (int)Slots.size(); }; + int GetSlotCount() const { return (int)Slots.size(); }; /** sets inventory size, for the first time */ void SetSlotCount(unsigned int size); @@ -267,19 +267,19 @@ int FindItem(const char *resref, unsigned int flags); bool DropItemAtLocation(unsigned int slot, unsigned int flags, Map *map, Point &loc); bool DropItemAtLocation(const char *resref, unsigned int flags, Map *map, Point &loc); - bool SetEquippedSlot(int slotcode, bool reequip); + bool SetEquippedSlot(int slotcode); int GetEquipped(); //right hand int GetEquippedSlot(); //left hand int GetShieldSlot(); - void AddSlotEffects( CREItem* slot, int type, bool reequip ); + void AddSlotEffects( CREItem* slot, int type); //void AddAllEffects(); /** Returns item in specified slot. Does NOT change inventory */ CREItem* GetSlotItem(unsigned int slot); bool ChangeItemFlag(unsigned int slot, ieDword value, int mode); /** Equips the item, don't use it directly for weapons */ - bool EquipItem(unsigned int slot, bool reequip); + bool EquipItem(unsigned int slot); bool UnEquipItem(unsigned int slot, bool removecurse); /** Returns equipped weapon */ CREItem *GetUsedWeapon(bool leftorright); Modified: gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-05-06 20:16:02 UTC (rev 4646) +++ gemrb/trunk/gemrb/plugins/FXOpcodes/FXOpc.cpp 2007-05-07 21:15:26 UTC (rev 4647) @@ -2462,12 +2462,20 @@ //0x71 Item:Equip int fx_equip_item (Actor* /*Owner*/, Actor* target, Effect* fx) { - if (core->QuerySlotEffects( fx->Parameter2 )) { - target->inventory.EquipItem(fx->Parameter2, true); - } + int eff = core->QuerySlotEffects( fx->Parameter2 ); + switch(eff) { + case SLOT_EFFECT_NONE: + case SLOT_EFFECT_MELEE: + target->inventory.SetEquippedSlot( fx->Parameter2 ); + break; + default: + target->inventory.EquipItem( fx->Parameter2 ); + break; + } target->ReinitQuickSlots(); return FX_NOT_APPLIED; } + //0x72 Dither int fx_dither (Actor* /*Owner*/, Actor* /*target*/, Effect* fx) { Modified: gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-05-06 20:16:02 UTC (rev 4646) +++ gemrb/trunk/gemrb/plugins/GUIScript/GUIScript.cpp 2007-05-07 21:15:26 UTC (rev 4647) @@ -6426,7 +6426,7 @@ // Note: this forcefully gets rid of any item currently // in the slot without properly unequipping it actor->inventory.SetSlotItemRes( ItemResRef, SlotID, Charge0, Charge1, Charge2 ); - actor->inventory.EquipItem(SlotID, true); + actor->inventory.EquipItem(SlotID); actor->RefreshEffects(); actor->ReinitQuickSlots(); } @@ -7392,7 +7392,7 @@ return RuntimeError( "Actor not found" ); } - int ret = actor->SetEquippedQuickSlot(slot, true); + int ret = actor->SetEquippedQuickSlot(slot); return PyInt_FromLong( ret ); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ave...@us...> - 2007-05-09 21:42:30
|
Revision: 4649 http://gemrb.svn.sourceforge.net/gemrb/?rev=4649&view=rev Author: avenger_teambg Date: 2007-05-09 14:42:29 -0700 (Wed, 09 May 2007) Log Message: ----------- added palette/gradient support to projectiles Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Projectile.cpp gemrb/trunk/gemrb/plugins/Core/Projectile.h gemrb/trunk/gemrb/plugins/Core/ProjectileServer.cpp gemrb/trunk/gemrb/plugins/PROImporter/PROImp.cpp Modified: gemrb/trunk/gemrb/plugins/Core/Projectile.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Projectile.cpp 2007-05-07 22:13:58 UTC (rev 4648) +++ gemrb/trunk/gemrb/plugins/Core/Projectile.cpp 2007-05-09 21:42:29 UTC (rev 4649) @@ -43,6 +43,8 @@ autofree = false; Extension = NULL; area = NULL; + palette = NULL; + //shadpal = NULL; Pos.empty(); Destination = Pos; Orientation = 0; @@ -62,6 +64,8 @@ if (effects) { delete effects; } + core->FreePalette(palette); + //core->FreePalette(shadpal); ClearPath(); } @@ -122,6 +126,23 @@ } } +//apply gradient colors +void Projectile::SetupPalette(Animation *anim[], Palette *&pal, ieByte *gradients) +{ + ieDword Colors[7]; + + for (int i=0;i<7;i++) { + Colors[i]=gradients[i]; + } + Sprite2D* spr = anim[0]->GetFrame(0); + if (spr) { + pal = core->GetVideoDriver()->GetPalette(spr)->Copy(); + } + if (pal) { + pal->SetupPaperdollColours(Colors, 0); + } +} + // load animations, start sound void Projectile::Setup() { @@ -131,12 +152,21 @@ memset(shadow,0,sizeof(shadow)); light = NULL; CreateAnimations(travel, BAMRes1, Seq1); + if (TFlags&PTF_COLOUR) { + SetupPalette(travel, palette, Gradients); + } if (TFlags&PTF_SHADOW) { CreateAnimations(shadow, BAMRes2, Seq2); + //if (TFlags&PTF_SHADOWCOLOR) { + // SetupPalette(shadow, shadpal, Gradients); + //} } if (TFlags&PTF_LIGHT) { //light = CreateLight(LightX, LightY, LightZ); } + //just for sure + core->FreePalette(palette); + palette=core->GetPalette(PaletteRes); } //control the phase change when the projectile reached its target @@ -431,7 +461,7 @@ } if (travel[face]) { Sprite2D *frame = travel[face]->NextFrame(); - video->BlitGameSprite( frame, Pos.x + screen.x, Pos.y + screen.y, flag, tint, NULL, NULL, &screen); + video->BlitGameSprite( frame, Pos.x + screen.x, Pos.y + screen.y, flag, tint, NULL, palette, &screen); } if (shadow[face]) { Modified: gemrb/trunk/gemrb/plugins/Core/Projectile.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Projectile.h 2007-05-07 22:13:58 UTC (rev 4648) +++ gemrb/trunk/gemrb/plugins/Core/Projectile.h 2007-05-09 21:42:29 UTC (rev 4649) @@ -30,6 +30,7 @@ #define PROJECTILE_H #include "../../includes/ie_types.h" +#include "Palette.h" #include "PathFinder.h" #include "CharAnimations.h" //contains MAX_ORIENT #include "Map.h" @@ -119,7 +120,7 @@ ieWord LightX; ieWord LightY; ieWord LightZ; - ieResRef Palette; + ieResRef PaletteRes; ieByte Gradients[7]; ieByte SmokeSpeed; ieByte SmokeGrad[7]; @@ -130,6 +131,8 @@ // ProjectileExtension *Extension; bool autofree; + Palette *palette; + //Palette *shadpal; //internals protected: //attributes from moveable object @@ -220,6 +223,7 @@ int GetShadowPos(int face); void SetPos(int face, int frame1, int frame2); void NextTarget(Point &p); + void SetupPalette(Animation *anim[], Palette *&pal, ieByte *gradients); }; #endif // PROJECTILE_H Modified: gemrb/trunk/gemrb/plugins/Core/ProjectileServer.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/ProjectileServer.cpp 2007-05-07 22:13:58 UTC (rev 4648) +++ gemrb/trunk/gemrb/plugins/Core/ProjectileServer.cpp 2007-05-09 21:42:29 UTC (rev 4649) @@ -86,7 +86,8 @@ int strlength = (ieByte *) (&pro->Extension)-(ieByte *) (&pro->Type); Projectile *old = projectiles[idx].projectile; memcpy(&pro->Type, &old->Type, strlength ); - if(old->Extension) { + //FIXME: copy extension data too, or don't alter the extension + if (old->Extension) { pro->Extension = old->Extension; } return pro; Modified: gemrb/trunk/gemrb/plugins/PROImporter/PROImp.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/PROImporter/PROImp.cpp 2007-05-07 22:13:58 UTC (rev 4648) +++ gemrb/trunk/gemrb/plugins/PROImporter/PROImp.cpp 2007-05-09 21:42:29 UTC (rev 4649) @@ -83,7 +83,7 @@ str->ReadWord( &s->LightZ ); str->ReadWord( &s->LightX ); str->ReadWord( &s->LightY ); - str->ReadResRef( s->Palette ); + str->ReadResRef( s->PaletteRes ); str->Read( s->Gradients, 7); str->Read( &s->SmokeSpeed, 1); str->Read( s->SmokeGrad, 7); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |