Note: New info added below!
Ok, not to say Frogboy's post wasn't helpful, but I was still left quite confused as to how to really dig in and make a good quest. I'm still not a master or anything, but I've gotten a few done, and wanted to share what I've learned so far. If you see mistakes, or have some more input, feel free to post away.
Ok, so let's start with a quest I had made for the adventure content pack. This will include everything I had to do to get it ALL to work. Lots of code here. The amount you do depends on how custom you make the quest (units, items, tiles). I'm not going to include the code for the tile though. However, if you want to look at everything here, it is included in ACP. The files you'd want to look at are ACP_CoreQuests, ACP_CoreQuestLocations, ACP_CoreQuestGoodieHuts, ACP_QuestUnits, ACP_QuestItems, and ACP_CoreAccessories.
1. Quest Definition
<QuestDef InternalName="Quest_Sage_Request">
<DisplayName>A Sage's Request</DisplayName>
<PrefQuestLoc>ACP_Sage1</PrefQuestLoc>
<Repeatable>0</Repeatable>
<TriggerChance>70</TriggerChance>
<Image>Academy_Medallion.png</Image>
<QuestClass>Minor</QuestClass>
<TriggerType>QuestLocation</TriggerType>
<TriggerOrigin>EventLocation</TriggerOrigin>
<SpawnRating>1</SpawnRating>
<Description> After arriving at the sage's home, he tells you how his assistant stole a scroll of his. He offers you to increase your spell researh in return for you getting the scroll back. </Description>
<ShortTextAccept>I will do it.</ShortTextAccept>
<ShortTextDeny>I don't feel like it today.</ShortTextDeny>
This is where things will look a little different than whats in frogboy's quest, or the earlier quests. There is no <SuccessText>, and also no GameModifier in the basic QuestDef tag. The game modifier will be under a different tag, as well as the successtext (although its called something else). There's also no reward tags like i've seen in other quests. I think you use those tags if you don't have any choices in your quest. If the player cannot choose his path through the quest (other than simply saying yes or no to the quest), then you use those tags. This caused me quite a lot of grief figuring out. All those tags I've left out seem to happen no matter what as long as you've accepted the quest. Since this quest has options, I left them out.Ok, so this is the starting definition of the quest. Questdef is the opening tag which contains all the necessary options of the quest (conditions, objectives, choices). Make sure you have an original internalname. Then the displayname is just what it sounds like. This is what's displayed at the top of all the popup windows for the quest.PreQuestLoc - This points to the preferred quest location. [See Quest Location Definition Below]Repeatable is pretty obvious. 0 for nonrepeatable (note: it may still spawn another location, but as soon as one has been "activated" or started, the others disappear). 1 for repeatable.TriggerChance - Again, fairly obvious, but it's how rare the quest is.Image - I haven't messed around with the images yet, but i imagine this is the graphic displayed when the quest first starts.QuestClass - already described by frogboyspawnrating - This is the Quest level of the quest (what level the player's quest level must be to do this quest)Description - This is whats displayed when you first start the quest. There appears to be no limit on text. The more you put here, the text will shrink a bit, and eventually a scroll will appear on the side.ShortTextAccept/Deny - What is displayed for accepting/denying the quest. If you leave these two out, it will default to yes or no.
So far, in this quest we have simply the choice of accepting the quest or not.
Now, some more code...
<QuestObjectiveDef InternalName="GetToAssistant">
<ObjectiveID>0</ObjectiveID>
<NextObjectiveID>1</NextObjectiveID>
<Description>That little bastard doesn't live far from here.</Description>
<PopupObjectiveMsg>1</PopupObjectiveMsg>
<GameModifier InternalName="MakeSageAssistantsHouse">
<ModType>Map</ModType>
<Attribute>CreateGoodieHut</Attribute>
<UnitClass>ACP_Sage_Assistant</UnitClass>
<StrVal>Sage's Assistant</StrVal>
<Radius>4</Radius>
</GameModifier>
Ok, so now we get to our first objective. I've been using the internalname just to make it easier to know what each objective is.ObjectiveID - Each objective has it's own number. It goes sequentially. Make sure each has it's own number.NextObjectiveID - The next objective to go to once this objective has been met.Description - This is what's displayed in the popupmessage when the objective starts (in this case, after you accept the quest - this is the 1st objective, remember?) [This is a small popup, so make it short, like a sentence or two]Popupobjectivemsg - This simply turns the Popup message on or off. So, if this is set to 0, the description tag above is ignored.Next is the game modifier to create the Sage's Assstant's home. That sage really wants his "scroll". The UnitClass is the Quest Location of the assistant's home. [This is defined in the goodiehuts below] StrVal is like displayname. I'm not sure where this is shown, however (the goodehut def does the hover over stuff) Radius is pretty obvious as well. The radius in tiles that the new location will be spawned.Ok, so to wrap up the quest so far...we've got the accepting of the quest, and the start of the first objective, which is to simply get to the assistant's home. Now, more code...<ChoiceText>When you get near the assistant's home, he appears to be waiting for you. He says that he knew the sage would send someone after him for the scroll. He's in dire need of money, and offers you the scroll for 50 gildar.</ChoiceText>
<ChoiceMedallion>Gfx\\Medallions\\K_Adventure.png</ChoiceMedallion>
<ChoiceMedallionFrame>Gfx\\Medallions\\Medallion_Frame_01.png</ChoiceMedallionFrame>
<!-- Choice 0 -->
<QuestChoiceDef>
<Description>Hmmm, I suppose I could spare 50 gildar.</Description>
<NextObjectiveID>1</NextObjectiveID>
<PopupMessage>The assistant thanks you profusely, and hands over the scroll.</PopupMessage>
<GameModifier InternalName="GoldPayment">
<ModType>Resource</ModType>
<Attribute>Gold</Attribute>
<Value>-50.0</Value>
<PerTurn>0</PerTurn>
</GameModifier>
<GameModifier InternalName="ReceiveScroll">
<ModType>GiveItem</ModType>
<Attribute>SageScroll</Attribute>
</GameModifier>
</QuestChoiceDef>
<!-- Choice 1 -->
<QuestChoiceDef>
<Description>You deserve to die, scum!</Description>
<NextObjectiveID>1</NextObjectiveID>
<!-- Create some bad guys, first one becomes the leader -->
<Encounter InternalName="SageAssistant">
<Liklihood>100</Liklihood>
<LevelLo>1</LevelLo>
<LevelHi>4</LevelHi>
<WillRespawn>0</WillRespawn>
<WanderingRadius>0</WanderingRadius>
<UnitInstance>
<UnitType>SageAssistant</UnitType>
<UnitName>Ranfor</UnitName>
<Level>1</Level>
</UnitInstance>
</Encounter>
<GameModifier InternalName="ReceiveScroll">
<ModType>GiveItem</ModType>
<Attribute>SageScroll</Attribute>
</GameModifier> </QuestChoiceDef>
<!-- Choice 2 -->
<QuestChoiceDef>
<Description>This is stupid. I'm done with this. (Leave)</Description>
<NextObjectiveID>-1</NextObjectiveID>
<PopupMessage>The old sage is disappointed and goes to cry in the corner.</PopupMessage>
</QuestChoiceDef>
Ok, so we have quite a bit up there. I really think this is where the meat of the quest system is. We all love choices! As you can see above, we have three different things we can to to continue. Explanations:ChoiceText - This is what's said when you first arrive at the assistant's home. [This appears to have a 400 character limit. I've restriced mine to under that, like around 390 to be safe.]ChoiceMedallion/ChoiceMedallionFrame - I haven't messed with these yet, I think it's the background image used for the choice window.QuestChoiceDef - These are nifty. You don't have to have an internalname, and they dont have to be numbered. The game just reads them all. You can do alot in here. It will allow you to use just about any Game Modifier you want. I put comments above each choice to make it clearer to see. Description - This is what's displayed as the player's choice. NextObjectiveID - The next objective to go to after this choice is made. If you put -1 here, it ends the quest. PopupMessage - This is what's displayed after this choice is made. (Note, you dont have to have a popup come up. If you leave this out, it won't display anything.) GameModifier - If you've modded, you should know about these. Just about anything works, EXCEPT if you want to give research points. Even the stardock created quests that are supposed to supply research don't actually work. This is yet another thing you don't have to have in a questchoice. Encounter - This will start a tactical battle. All the stuff in this tag is easy enough to get from reading it. One thing I will mention is that UnitType is the tag to call the "monster" (using their internalname). And UnitName is just the name it displays on the unit's card in battle. Like it says in the comment, the first unit gets designated leader. This is useful if you just want to make sure the player kills just the leader of a group.Alright, so now we know the Sage had his scroll stolen by his assistant, and we've had the player go to the Assistant's house to retreive it. When the player gets there the assistant tells him that he's broke and needs the money. So, we give the player 3 choices:1> Give the assistant 50 gildar, and get the scroll.2> Fight and kill the assistant, get the scroll.3> Give up, and stop the quest. No reward, nothing. It's done. (the sage cries)<QuestConditionDef InternalName="Part1_Complete">
<Class>Success</Class>
<Type>ClearGoodieHut</Type>
<TextData>ACP_Sage_Assistant</TextData>
<Flag>RevealTarget</Flag>
</QuestConditionDef>
</QuestObjectiveDef>
And here we have the conditiondef. again I just used the internalname to make it easier to read the quest in the xmlClass is either Success or Failure. I haven't messed with failure enough. You have to make sure to place this in the right pace within the whole quest structure. For this quest, it's after the questchoices, but inside the first questobjectivedef tag. This is what will advance the player to the next objective.Type is explained in Frogboy's post. I'm not sure every tag is working, but I know this one is. KillMonster also does as well.The revealtarget flag only seems to work in this instance. But I havent played with it too much.
<QuestObjectiveDef InternalName="ReturnTheScroll">
<ObjectiveID>1</ObjectiveID>
<QuestEnd>1</QuestEnd>
<Description>Bring the scroll back to the sage.</Description>
<PopupObjectiveMsg>1</PopupObjectiveMsg>
<QuestConditionDef InternalName="Scrollisreturned.">
<Class>Success</Class>
<Type>ReturnItemToQuestLocation</Type>
<TextData>SageScroll</TextData>
<NumericData>1</NumericData>
<CompletionText> You have returned the smelly "scroll" to the Sage. As promised, he hands over the 20 mysterious spell points. </CompletionText>
<GameModifier InternalName="Reward1">
<ModType>Resource</ModType>
<Attribute>SpellPoints</Attribute>
<Value>20.00</Value>
<PerTurn>0</PerTurn>
</GameModifier>
</QuestConditionDef>
</QuestObjectiveDef>
</QuestDef>
And here is the last objective. Make the player go back to the quest location (sage's home) to return the "scroll" (You'll understand why I keep putting scroll in quotes when you see the item defs later on).There's really nothing new in the above code, it just completes the quest. One thing I do want to mention is don't forget to add <NumericData> to the conditiondef if you're using the returnitemtoquestlocation. Otherwise, the game seems to accept "0" of the item to want returned.CompletionText - This is what's displayed when you complete the quest.So, we've managed to get the scroll, and return it and get our reward of 20 spellpoints. One thing I noticed though...make sure you are researching spells. If you're not (like in the very beginning of the game), then this wont do anything. This is another little thing that caused me headaches. Even if you aren't producing any spellpoints, if you have some spells "learning", it will complete when finishing the quest. Ok, now that's the meat of the quest definition. Now, we have to define a bunch of other things as well.
2. Quest Location Definition
Ok, this is where we make the quest able to show up on the map. Without this, you won't see your quest.
<QuestLocationType InternalName="ACP_Sage1">
<Name>Sage's estate</Name>
<Description>This estate is something we may want to check out. It appears the sage needs some help.</Description>
<Rarity>70</Rarity>
<Medallions>
<All>Building_Inn1.png</All>
</Medallions>
<TileDesign>ACP_Sage1</TileDesign>
<DrawnIcon>Gfx/TacticalIcons/K_Inn1.png</DrawnIcon>
<Destructable>0</Destructable>
<IconSize>75</IconSize>
</QuestLocationType>
This is what will display your new quest on the map. This also is what dictates what is said when you hover over the tile on the map. Everything here is pretty intuitive. You should only need this for the starting quest tile. Any other locations you send the player in your quest gets a goodiehut definition. [See below]
3. GoodieHut Definition
<GoodieHutType InternalName="ACP_Sage_Assistant">
<Name>Sage's Assistant's Home</Name>
<SpawnRating>-1</SpawnRating>
<TileDesign>ACP_Sage_Assistant</TileDesign>
<Destructable>1</Destructable>
<Description>This is the home of the sage's assistant.</Description>
</GoodieHutType>
This is also easy enough. This will allow your spawned location defined in the questdef to actually show up on the map. Without this definition, your quest will just not work (if you cant get to the location, you cant progress in objectives). Just make sure to add the SpawnRating of -1 so that it doesnt spawn on a map as a notable location. A note here. You can use goodiehuts to spawn an encounter as well. Leave out the Description and TileDesign tags (for cleanliness), and stick your Encounter tag in here. This way, in the questdef you can use the creategoodiehut tag and point to the goodiehut you made with the encounter to make the player go somewhere else and fight some dudes/dudettes.Ok, so these first 3 topics I've covered are what's absolutely necessary for your quest to work properly. You may have to move things around for your own quest depending on how you setup choices. There doesn't seem to be a limit with choices, or objectives (though i havent pushed it much, because as you can see, it's quite a long process to make a quest).I also suggest Frogboy's idea of making a small map with two islands, and 2 start points (1 on each island) to make testing a bit quicker/easier.Just a recap, here's how the quest def should look like with just the main tags for this quest:<QuestDef> <QuestObjectiveDef> <QuestChoiceDefs> <GameModifier> <QuestConditionDef> <QuestObjectiveDef> <QuestConditionDef>I hope the above makes sense. Anyways, I was going to post all the other code, but I don't see the point. There's code for a custom unit (the sage's assistant), and the sage scroll (the reason I kept putting quotes around scroll is because I was lazy and just copied the deadrat item, and changed the internalname. Then I thought it was kind of funny, and left it.)The only thing to add is <QuestItem>1</QuestItem> to a quest item xml, and <QuestUnit>1</QuestUnit> to the unit xml. Well, this post took me a good hour or so to write out. I hope this clears up some things for people when trying to make a quest.
Ok, the above is great for most quests, but what if you want to have choices right after accepting the quest? The latest quest I was working on, I wanted to do this. Let me explain the quest.
Tomb Of Hagall
Ok, so you step into the tile, and you are asked if you're sure you want to enter the tomb (accept the quest or not).
Then, if you say yes, you are prompted with text explaining that you've looked around, and found a room with an inscription warning of a monster encounter. Again, you are presented the choice of do you want to continue? If you say yes, an encounter is spawned, and along with the quest you go.
This through me for a loop for a while. It's easy to do the above if you first spawn a goodiehut for the user to go to, THEN present choices. The way I got around this was to create a false objective with no conditions. I'll post the quest here and break it down to make it easier to see what I did.
<QuestDef InternalName="Quest_Tomb_Of_Hagall1">
<DisplayName>Tomb Of Hagall</DisplayName>
<PrefQuestLoc>ACP_Tomb_Of_Hagall1</PrefQuestLoc>
<Repeatable>0</Repeatable>
<TriggerChance>70</TriggerChance>
<Image>Academy_Medallion.png</Image>
<QuestClass>Minor</QuestClass>
<TriggerType>QuestLocation</TriggerType>
<TriggerOrigin>EventLocation</TriggerOrigin>
<SpawnRating>2</SpawnRating>
<Description> Hagall was a master spellcaster who lived in the times of the Titans. Near the end of any written, or otherwise, history of him ends with him researching powerful new enchantment spells that affect the global empire. Some say he went mad in his old age, so it may be wise to be careful. Are you sure you would like to enter the tomb? </Description>
<QuestObjectiveDef InternalName="Blanktoinitiatechoices">
<ObjectiveID>0</ObjectiveID>
<NextObjectiveID>1</NextObjectiveID>
<Description>Go take care of the ravenous umberdroths.</Description>
<PopupObjectiveMsg>0</PopupObjectiveMsg>
</QuestObjectiveDef>
Ok, so you see the "blank" objective. I've set popupobjectivemsg to 0 so there is no popup, and it's invisible to the user. Honestly, I may not need this after all, but I got the quest to work 100% correctly, so I'm leaving it for now.
<QuestObjectiveDef InternalName="Fighttheguardian">
<ObjectiveID>1</ObjectiveID>
<NextObjectiveID>2</NextObjectiveID>
<Description>Go take care of the ravenous umberdroths.</Description>
<PopupObjectiveMsg>0</PopupObjectiveMsg>
<ChoiceText>After wandering around the senseless corridors of the tomb, you come to what seems to be the wizard's old study. A warning is etched into the wall warning all intruders of the protector inside. Are you sure you want to enter?</ChoiceText>
<ChoiceMedallion>Gfx\\Medallions\\K_Adventure.png</ChoiceMedallion> <ChoiceMedallionFrame>Gfx\\Medallions\\Medallion_Frame_01.png</ChoiceMedallionFrame>
<QuestChoiceDef>
<Description>Yes, I'm not afraid of some "protector"!</Description>
<NextObjectiveID>2</NextObjectiveID>
<Encounter InternalName="ArmyFight">
<Liklihood>100</Liklihood>
<LevelLo>1</LevelLo>
<LevelHi>4</LevelHi>
<WillRespawn>0</WillRespawn>
<WanderingRadius>0</WanderingRadius>
<UnitInstance>
<UnitType>Skeleton1</UnitType>
<UnitName>Hagall's Protector</UnitName>
<Level>3</Level>
</UnitInstance>
</Encounter>
</QuestChoiceDef>
<QuestChoiceDef>
<Description>No, I'm too weak to fight anything right now.</Description>
<NextObjectiveID>-1</NextObjectiveID>
</QuestChoiceDef>
</QuestObjectiveDef>
Ok, here is where we spawn the encounter (or end the quest if the user doesn't want to fight). Notice the lack of a condition again. The condition will be in the next objective.
<QuestObjectiveDef InternalName="DecideaboutScroll">
<ObjectiveID>2</ObjectiveID>
<NextObjectiveID>3</NextObjectiveID>
<PopupObjectiveMsg>0</PopupObjectiveMsg>
<ChoiceText>On the old wizard's desk is what appears to be a rolled up scroll. The fact that it's glowing tells you it's something special. What do you want to do?</ChoiceText> <ChoiceMedallion>Gfx\\Medallions\\K_Adventure.png</ChoiceMedallion> <ChoiceMedallionFrame>Gfx\\Medallions\\Medallion_Frame_01.png</ChoiceMedallionFrame>
<QuestChoiceDef>
<Description>Let's see what's in that scroll!</Description>
<NextObjectiveID>3</NextObjectiveID>
<PopupMessage>When you read the scroll, everything in the room vanishes. When you look back at the scroll, you notice the text has disappeared and revealed a map to a secret location to one of Hagall's last known enchantment scrolls. You better get there before someone else does!</PopupMessage>
</QuestChoiceDef>
<QuestChoiceDef>
<Description>I have a bad feeling about that scroll. Let's just take his other books back to our scholars.</Description> <NextObjectiveID>-1</NextObjectiveID>
<PopupMessage>The books have made it easier for your scholars to learn spells! You've gained 15 spellpoints!</PopupMessage>
<GameModifier>
<ModType>Resource</ModType>
<Attribute>Spellpoints</Attribute>
<Value>15.0</Value>
<PerTurn>0</PerTurn>
</GameModifier>
</QuestChoiceDef>
<QuestConditionDef InternalName="Part1_Complete">
<Class>Success</Class>
<Type>KillMonster</Type>
<TextData>Skeleton1</TextData>
<MoreTextData>Hagall's Protector</MoreTextData>
<NumericData>1</NumericData>
</QuestConditionDef>
</QuestObjectiveDef>
Ok, here's were we see the condition for killing the protector from the previous objective. This objective will "run" when the skeleton is killed. (Read the descriptions to get an idea whats going on in the quest). For some reason, I had to create another objective in order to spawn the goodiehut to receive the reward (I did this so the reward could be randomized - see goodiehuts for how to do that - as I don't know of a way to do it in quests).
<QuestObjectiveDef InternalName="Gettoswamptree">
<ObjectiveID>3</ObjectiveID>
<NextObjectiveID>-1</NextObjectiveID>
<PopupObjectiveMsg>0</PopupObjectiveMsg>
<GameModifier InternalName="MakeSageAssistantsHouse">
<ModType>Map</ModType>
<Attribute>CreateGoodieHut</Attribute>
<UnitClass>ACP_Swamp_Tree_Quest</UnitClass>
<StrVal>Swamp Tree</StrVal>
<Radius>6</Radius>
</GameModifier>
</QuestObjectiveDef>
</QuestDef>
Again here, there's no condition, as the user has already "won" the quest. This was the only way I was able to get the goodiehut to spawn.
I didn't post the Quest Location Definition, or the goodiehut description, as I didn't do anything differently than I had previously explained above.
The order with which you do everything is tricky to get, but possible. I hope this latest installment helps people create more different quests.
UPDATE:
While fixing up the quests in ACP v0.99, I realized there was a slight problem with the above. Everything works, but if you chose to fight the assistant, it first shows the next objective, THEN you go into the fight. After the fight, there is no text, or info, because it came up before the fight started. To get around this, I added another Objective along the way. Here is what I ended up with for the quest starting at the first objective:
<QuestObjectiveDef InternalName="GetToAssistant">
<ObjectiveID>0</ObjectiveID>
<QuestObjectiveDef InternalName="GetToAssistant">
<ObjectiveID>0</ObjectiveID>
<NextObjectiveID>1</NextObjectiveID>
<Description>That little bastard doesn't live far from here.</Description>
<PopupObjectiveMsg>1</PopupObjectiveMsg>
<GameModifier InternalName="MakeSageAssistantsHouse">
<ModType>Map</ModType>
<Attribute>CreateGoodieHut</Attribute>
<UnitClass>ACP_Sage_Assistant</UnitClass>
<StrVal>Sage's Assistant</StrVal>
<Radius>4</Radius>
</GameModifier>
<ChoiceText>When you get near the assistant's home, he appears to be waiting for you. He says that he knew the sage would send someone after him for the scroll. He's in dire need of money, and offers you the scroll for 50 gildar.</ChoiceText>
<ChoiceMedallion>Gfx\\Medallions\\K_Adventure.png</ChoiceMedallion><ChoiceMedallionFrame>Gfx\\Medallions\\Medallion_Frame_01.png</ChoiceMedallionFrame>
<!-- Choice 0 -->
<QuestChoiceDef>
<Description>Hmmm, I suppose I could spare 50 gildar.</Description>
<NextObjectiveID>1</NextObjectiveID>
<PopupMessage>The assistant thanks you profusely, and hands over the scroll.</PopupMessage>
<GameModifier InternalName="GoldPayment">
<ModType>Resource</ModType>
<Attribute>Gold</Attribute>
<Value>-50.0</Value>
<PerTurn>0</PerTurn>
</GameModifier>
<GameModifier InternalName="ReceiveScroll">
<ModType>GiveItem</ModType>
<Attribute>SageScroll</Attribute>
</GameModifier>
</QuestChoiceDef>
<!-- Choice 1 -->
<QuestChoiceDef>
<Description>You deserve to die, scum!</Description>
<NextObjectiveID>2</NextObjectiveID>
<!-- Create some bad guys, first one becomes the leader -->
<Encounter InternalName="SageAssistant">
<Liklihood>100</Liklihood>
<LevelLo>1</LevelLo>
<LevelHi>4</LevelHi>
<WillRespawn>0</WillRespawn>
<WanderingRadius>0</WanderingRadius>
<UnitInstance>
<UnitType>SageAssistant</UnitType>
<UnitName>Ranfor</UnitName>
<Level>1</Level>
</UnitInstance>
</Encounter>
</QuestChoiceDef>
<!-- Choice 2 -->
<QuestChoiceDef>
<Description>This is stupid. I'm done with this. (Leave)</Description>
<NextObjectiveID>-1</NextObjectiveID>
<!-- Create some bad guys, first one becomes the leader -->
<PopupMessage>The old sage is disappointed and goes to cry in the corner.</PopupMessage>
</QuestChoiceDef>
<QuestConditionDef InternalName="Part1_Complete">
<Class>Success</Class>
<Type>ClearGoodieHut</Type>
<TextData>ACP_Sage_Assistant</TextData>
<Flag>RevealTarget</Flag>
</QuestConditionDef>
</QuestObjectiveDef>
<QuestObjectiveDef InternalName="ReturnTheScroll">
<ObjectiveID>1</ObjectiveID>
<QuestEnd>1</QuestEnd>
<Description>Bring the scroll back to the sage.</Description>
<PopupObjectiveMsg>1</PopupObjectiveMsg>
<QuestConditionDef InternalName="Scrollisreturned">
<Class>Success</Class>
<Type>ReturnItemToQuestLocation</Type>
<TextData>SageScroll</TextData>
<NumericData>1</NumericData>
<CompletionText> You have returned the smelly "scroll" to the Sage. As promised, he hands over the 20 mysterious spell points. </CompletionText>
<GameModifier InternalName="Reward1">
<ModType>Resource</ModType>
<Attribute>SpellPoints</Attribute>
<Value>20.00</Value>
<PerTurn>0</PerTurn>
</GameModifier>
</QuestConditionDef>
</QuestObjectiveDef>
Notice that there is a third objective (ID of 2). This is where we are able to prevent the screen from popping up before the fight, instead of after. It's essentially the same as objective 1, only with an added condition, of killing the assistant. Once the assistant is killed, you then get the message (Bring the scroll back to the sage) from the condition being met (assistant dead). Now, the whole quest operates as it should.
I should also mention that the sage assistant is defined elsewhere in ACP. The sage's scroll is setup as a "treasure" for killing the assistant.