Instructions Jenkins Doxygen

[Changed] go_to_theater to provide spawnedMobileList to the 50/1650/2
authorLoshult <loshult@swgemu.com>
Thu, 8 May 2014 19:34:10 +0000 (19:34 +0000)
committerLoshult <loshult@swgemu.com>
Thu, 8 May 2014 19:39:28 +0000 (19:39 +0000)
onSuccessfulSpawn method.
[Added] Activation of quest when the sith shadow intro theater is
spawned.
[Added] Theater datapad as loot to the first sith shadow in the sith
shadow intro theater.
[Added] Completion of quest when looting the datapad from the sith
shadown in the intro camp.

Change-Id: I23125ee8b195fcfff258863fb110365a1e1afee4

MMOCoreORB/bin/scripts/loot/groups/sith_shadow_intro_theater_datapad.lua [new file with mode: 0644]
MMOCoreORB/bin/scripts/loot/items.lua
MMOCoreORB/bin/scripts/loot/items/quest/theater_datapad.lua [new file with mode: 0644]
MMOCoreORB/bin/scripts/managers/jedi/village/sith_shadow_intro_theater.lua
MMOCoreORB/bin/scripts/managers/jedi/village/tests/sith_shadow_intro_theater_Test.lua
MMOCoreORB/bin/scripts/object/tangible/loot/quest/force_sensitive/theater_datapad.lua
MMOCoreORB/bin/scripts/quest/tasks/go_to_theater.lua
MMOCoreORB/bin/scripts/quest/tasks/tests/go_to_theater_Test.lua

diff --git a/MMOCoreORB/bin/scripts/loot/groups/sith_shadow_intro_theater_datapad.lua b/MMOCoreORB/bin/scripts/loot/groups/sith_shadow_intro_theater_datapad.lua
new file mode 100644 (file)
index 0000000..b827194
--- /dev/null
@@ -0,0 +1,12 @@
+--Automatically generated by SWGEmu Spawn Tool v0.12 loot editor.
+
+sith_shadow_intro_theater_datapad = {
+       description = "",
+       minimumLevel = 0,
+       maximumLevel = 0,
+       lootItems = {
+               {itemTemplate = "theater_datapad", weight = 10000000}
+       }
+}
+
+addLootGroupTemplate("sith_shadow_intro_theater_datapad", sith_shadow_intro_theater_datapad)
index d5752d7..4b2d2cc 100644 (file)
@@ -439,6 +439,7 @@ includeFile("items/painting/valley_view_painting.lua")
 
 --quest sub-folder
 includeFile("items/quest/waypoint_datapad.lua")
+includeFile("items/quest/theater_datapad.lua")
 
 --recycler sub-folder
 includeFile("items/recycler/agitator_motor_schematic.lua")
diff --git a/MMOCoreORB/bin/scripts/loot/items/quest/theater_datapad.lua b/MMOCoreORB/bin/scripts/loot/items/quest/theater_datapad.lua
new file mode 100644 (file)
index 0000000..6cbf877
--- /dev/null
@@ -0,0 +1,14 @@
+--Automatically generated by SWGEmu Spawn Tool v0.12 loot editor.
+
+theater_datapad = {
+       minimumLevel = 0,
+       maximumLevel = -1,
+       customObjectName = "",
+       directObjectTemplate = "object/tangible/loot/quest/force_sensitive/theater_datapad.iff",
+       craftingValues = {
+       },
+       customizationStringNames = {},
+       customizationValues = {}
+}
+
+addLootItemTemplate("theater_datapad", theater_datapad)
index 71db896..d82829a 100644 (file)
@@ -1,5 +1,7 @@
 local GoToTheater = require("quest.tasks.go_to_theater")
 local ObjectManager = require("managers.object.object_manager")
+local QuestManager = require("managers.quest.quest_manager")
+local SpawnMobiles = require("utils.spawn_mobiles")
 require("utils.helpers")
 
 SithShadowIntroTheater = GoToTheater:new {
@@ -21,12 +23,67 @@ SithShadowIntroTheater = GoToTheater:new {
        onEnteredActiveArea = nil
 }
 
-function SithShadowIntroTheater:onEnteredActiveArea(pCreatureObject, spawnedMobilesList)
-       foreach(spawnedMobilesList, function(pMobile)
+-- Check if the sith shadow is the first one spawned for the player.
+-- @param pSithShadow pointer to the sith shadow.
+-- @param pCreatureObject pointer to the creature object of the player.
+-- @return true if the sith shadow is the first one spawned for the player.
+function SithShadowIntroTheater:isTheFirstSithShadowOfThePlayer(pSithShadow, pCreatureObject)
+       local spawnedSithShadows = SpawnMobiles.getSpawnedMobiles(pCreatureObject, self.taskName)
+
+       if spawnedSithShadows ~= nil then
+               return ObjectManager.withCreatureObject(spawnedSithShadows[1], function(sithShadowInList)
+                       return ObjectManager.withCreatureObject(pSithShadow, function(sithShadow)
+                               return sithShadowInList:getObjectID() == sithShadow:getObjectID()
+                       end) == true
+               end) == true
+       else
+               return false
+       end
+end
+
+-- Create the waypoint data pad as loot on the sith shadow.
+-- @param pSithShadow pointer to the creature object of the sith shadow.
+function SithShadowIntroTheater:addWaypointDatapadAsLoot(pSithShadow)
+       ObjectManager.withInventoryPointer(pSithShadow, function(pInventory)
+               createLoot(pInventory, "sith_shadow_intro_theater_datapad", 0, true)
+       end)
+end
+
+-- Event handler for the LOOTCREATURE event on one of the sith shadows.
+-- @param pLootedCreature pointer to the sith shadow creature that is being looted.
+-- @param pLooter pointer to the creature object of the looter.
+-- @param nothing unused variable for the default footprint of event handlers.
+-- @return 1 if the correct player looted the creature to remove the observer, 0 otherwise to keep the observer.
+function SithShadowIntroTheater:onLoot(pLootedCreature, pLooter, nothing)
+       Logger:log("Looting the sith shadow.", LT_INFO)
+       if self:isTheFirstSithShadowOfThePlayer(pLootedCreature, pLooter) then
+               self:addWaypointDatapadAsLoot(pLootedCreature)
+               QuestManager.completeQuest(pLooter, QuestManager.quests.FS_THEATER_CAMP)
+               return 1
+       end
+
+       return 0
+end
+
+-- Event handler for the enter active area event.
+-- The event will cause all spawned Sith Shadows to attack the player.
+-- @param pCreatureObject pointer to the creature object of the player.
+-- @param spawnedSithShadowsList list with pointers to the spawned sith shadows.
+function SithShadowIntroTheater:onEnteredActiveArea(pCreatureObject, spawnedSithShadowsList)
+       foreach(spawnedSithShadowsList, function(pMobile)
                ObjectManager.withCreatureAiAgent(pMobile, function(mobile)
                        mobile:setFollowObject(pCreatureObject)
                end)
        end)
 end
 
+-- Event handler for the successful spawn event.
+-- The event will activate the FS_THEATER_CAMP quest for the player.
+-- @param pCreatureObject pointer to the creature object of the player.
+-- @param spawnedSithShadowsList list with pointers to the spawned sith shadows.
+function SithShadowIntroTheater:onSuccessfulSpawn(pCreatureObject, spawnedSithShadowsList)
+       QuestManager.activateQuest(pCreatureObject, QuestManager.quests.FS_THEATER_CAMP)
+       createObserver(LOOTCREATURE, self.taskName, "onLoot", spawnedSithShadowsList[1])
+end
+
 return SithShadowIntroTheater
index 7f9c87d..32d4766 100644 (file)
 local SithShadowIntroTheater = require("managers.jedi.village.sith_shadow_intro_theater")
 local DirectorManagerMocks = require("screenplays.mocks.director_manager_mocks")
+local QuestManagerMocks = require("managers.quest.mocks.quest_manager_mocks")
+local SpawnMobilesMocks = require("utils.mocks.spawn_mobiles_mocks")
 
 describe("SithShadowIntroTheater", function()
        local pCreatureObject = { "creatureObjectPointer" }
-       local pSpawnedMobile1 = { "spawnedMobile1Pointer" }
-       local pSpawnedMobile2 = { "spawnedMobile2Pointer" }
-       local spawnedMobile1
-       local spawnedMobile2
-       local spawnedMobilesList = { pSpawnedMobile1, pSpawnedMobile2 }
+       local pFirstSithShadow = { "firstSithShadowObjectPointer" }
+       local pSecondSithShadow = { "spawnedMobile2Pointer" }
+       local firstSithShadowObject
+       local secondSithShadowObject
+       local spawnedSithShadowList = { pFirstSithShadow, pSecondSithShadow }
+       local pInventory = { "inventoryPointer" }
+       local firstSithShadowId = 12345
+       local secondSithShadowId = 23456
+       local pDatapad = { "datapadPointer" }
+       local datapad
 
        setup(function()
                DirectorManagerMocks.mocks.setup()
+               QuestManagerMocks.mocks.setup()
+               SpawnMobilesMocks.mocks.setup()
        end)
 
        teardown(function()
                DirectorManagerMocks.mocks.teardown()
+               QuestManagerMocks.mocks.teardown()
+               SpawnMobilesMocks.mocks.teardown()
        end)
 
        before_each(function()
                DirectorManagerMocks.mocks.before_each()
+               QuestManagerMocks.mocks.before_each()
+               SpawnMobilesMocks.mocks.before_each()
 
-               spawnedMobile1 = {}
-               spawnedMobile1.setFollowObject = spy.new(function() end)
-               DirectorManagerMocks.aiAgents[pSpawnedMobile1] = spawnedMobile1
+               firstSithShadowObject = {}
+               firstSithShadowObject.setFollowObject = spy.new(function() end)
+               firstSithShadowObject.getObjectID = spy.new(function() return firstSithShadowId end)
+               firstSithShadowObject.getSlottedObject = spy.new(function() return pInventory end)
+               DirectorManagerMocks.creatureObjects[pFirstSithShadow] = firstSithShadowObject
+               DirectorManagerMocks.aiAgents[pFirstSithShadow] = firstSithShadowObject
 
-               spawnedMobile2 = {}
-               spawnedMobile2.setFollowObject = spy.new(function() end)
-               DirectorManagerMocks.aiAgents[pSpawnedMobile2] = spawnedMobile2
+               secondSithShadowObject = {}
+               secondSithShadowObject.setFollowObject = spy.new(function() end)
+               secondSithShadowObject.getObjectID = spy.new(function() return secondSithShadowId end)
+               DirectorManagerMocks.creatureObjects[pSecondSithShadow] = secondSithShadowObject
+               DirectorManagerMocks.aiAgents[pSecondSithShadow] = secondSithShadowObject
        end)
 
        describe("onEnteredActiveArea", function()
                describe("When a player enters the active area", function()
                        it("Should set all spawned sith shadows to attack the player.", function()
-                               SithShadowIntroTheater:onEnteredActiveArea(pCreatureObject, spawnedMobilesList)
+                               SithShadowIntroTheater:onEnteredActiveArea(pCreatureObject, spawnedSithShadowList)
 
-                               assert.spy(spawnedMobile1.setFollowObject).was.called_with(spawnedMobile1, pCreatureObject)
-                               assert.spy(spawnedMobile2.setFollowObject).was.called_with(spawnedMobile2, pCreatureObject)
+                               assert.spy(firstSithShadowObject.setFollowObject).was.called_with(firstSithShadowObject, pCreatureObject)
+                               assert.spy(secondSithShadowObject.setFollowObject).was.called_with(secondSithShadowObject, pCreatureObject)
+                       end)
+               end)
+       end)
+
+       describe("onSuccessfulSpawn", function()
+               describe("When a sith shadow intro camp is spawned", function()
+                       it("Should activate the quest for the player that the camp belongs to.", function()
+                               SithShadowIntroTheater:onSuccessfulSpawn(pCreatureObject, spawnedSithShadowList)
+
+                               assert.spy(QuestManagerMocks.activateQuest).was.called_with(pCreatureObject, QuestManagerMocks.quests.FS_THEATER_CAMP)
+                       end)
+
+                       it("Should register an observer onLoot of the first spawned mobile.", function()
+                               SithShadowIntroTheater:onSuccessfulSpawn(pCreatureObject, spawnedSithShadowList)
+
+                               assert.spy(createObserver).was.called_with(LOOTCREATURE, SithShadowIntroTheater.taskName, "onLoot", pFirstSithShadow)
+                       end)
+               end)
+       end)
+
+       describe("onLoot", function()
+               describe("When called with a pointer to a creature and a pointer to the looter", function()
+                       it("Should get the list of spawned sith shadows for the looter.", function()
+                               SithShadowIntroTheater:onLoot(pFirstSithShadow, pCreatureObject, 0)
+
+                               assert.spy(SpawnMobilesMocks.getSpawnedMobiles).was.called_with(pCreatureObject, SithShadowIntroTheater.taskName)
+                       end)
+
+                       describe("and the player has a list of spawned sith shadows", function()
+                               before_each(function()
+                                       SpawnMobilesMocks.getSpawnedMobiles = spy.new(function() return spawnedSithShadowList end)
+                               end)
+
+                               it("Should get the id of the first sith shadow in the list", function()
+                                       SithShadowIntroTheater:onLoot(pSecondSithShadow, pCreatureObject, 0)
+
+                                       assert.spy(firstSithShadowObject.getObjectID).was.called_with(firstSithShadowObject)
+                               end)
+
+                               it("Should get the id of the looted creature", function()
+                                       SithShadowIntroTheater:onLoot(pSecondSithShadow, pCreatureObject, 0)
+
+                                       assert.spy(secondSithShadowObject.getObjectID).was.called_with(secondSithShadowObject)
+                               end)
+
+                               describe("and both ids are identical", function()
+                                       it("Should create loot in the inventory of the sith shadow.", function()
+                                               SithShadowIntroTheater:onLoot(pFirstSithShadow, pCreatureObject, 0)
+
+                                               assert.spy(createLoot).was.called_with(pInventory, "sith_shadow_intro_theater_datapad", 0, true)
+                                       end)
+
+                                       it("Should return 1 to remove the observer.", function()
+                                               assert.same(1, SithShadowIntroTheater:onLoot(pFirstSithShadow, pCreatureObject, 0))
+                                       end)
+                               end)
+
+                               describe("and both ids are not identical", function()
+                                       it("Should not create loot in the inventory of the looted sith shadow.", function()
+                                               SithShadowIntroTheater:onLoot(pSecondSithShadow, pCreatureObject, 0)
+
+                                               assert.spy(createLoot).was.not_called()
+                                       end)
+
+                                       it("Should return 0 to keep the observer.", function()
+                                               assert.same(0, SithShadowIntroTheater:onLoot(pSecondSithShadow, pCreatureObject, 0))
+                                       end)
+                               end)
+
+                               it("Should complete the sith shadow ambush quests.", function()
+                                       SithShadowIntroTheater:onLoot(pFirstSithShadow, pCreatureObject, 0)
+
+                                       assert.spy(QuestManagerMocks.completeQuest).was.called_with(pCreatureObject, QuestManagerMocks.quests.FS_THEATER_CAMP)
+                               end)
+                       end)
+
+                       describe("and the player has no spawned sith shadows", function()
+                               before_each(function()
+                                       SpawnMobilesMocks.getSpawnedMobiles = spy.new(function() return nil end)
+                               end)
+
+                               it("Should not create loot in the inventory of the looted sith shadow.", function()
+                                       SithShadowIntroTheater:onLoot(pFirstSithShadow, pCreatureObject, 0)
+
+                                       assert.spy(createLoot).was.not_called()
+                               end)
+
+                               it("Should return 0 to keep the observer.", function()
+                                       assert.same(0, SithShadowIntroTheater:onLoot(pFirstSithShadow, pCreatureObject, 0))
+                               end)
                        end)
                end)
        end)
index 8dbca8c..fef94c0 100644 (file)
@@ -3,46 +3,47 @@
 
 --This File is part of Core3.
 
---This program is free software; you can redistribute 
---it and/or modify it under the terms of the GNU Lesser 
+--This program is free software; you can redistribute
+--it and/or modify it under the terms of the GNU Lesser
 --General Public License as published by the Free Software
---Foundation; either version 2 of the License, 
+--Foundation; either version 2 of the License,
 --or (at your option) any later version.
 
---This program is distributed in the hope that it will be useful, 
---but WITHOUT ANY WARRANTY; without even the implied warranty of 
---MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+--This program is distributed in the hope that it will be useful,
+--but WITHOUT ANY WARRANTY; without even the implied warranty of
+--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 --See the GNU Lesser General Public License for
 --more details.
 
---You should have received a copy of the GNU Lesser General 
+--You should have received a copy of the GNU Lesser General
 --Public License along with this program; if not, write to
 --the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
---Linking Engine3 statically or dynamically with other modules 
---is making a combined work based on Engine3. 
---Thus, the terms and conditions of the GNU Lesser General Public License 
+--Linking Engine3 statically or dynamically with other modules
+--is making a combined work based on Engine3.
+--Thus, the terms and conditions of the GNU Lesser General Public License
 --cover the whole combination.
 
---In addition, as a special exception, the copyright holders of Engine3 
---give you permission to combine Engine3 program with free software 
---programs or libraries that are released under the GNU LGPL and with 
---code included in the standard release of Core3 under the GNU LGPL 
---license (or modified versions of such code, with unchanged license). 
---You may copy and distribute such a system following the terms of the 
---GNU LGPL for Engine3 and the licenses of the other code concerned, 
---provided that you include the source code of that other code when 
+--In addition, as a special exception, the copyright holders of Engine3
+--give you permission to combine Engine3 program with free software
+--programs or libraries that are released under the GNU LGPL and with
+--code included in the standard release of Core3 under the GNU LGPL
+--license (or modified versions of such code, with unchanged license).
+--You may copy and distribute such a system following the terms of the
+--GNU LGPL for Engine3 and the licenses of the other code concerned,
+--provided that you include the source code of that other code when
 --and as the GNU LGPL requires distribution of source code.
 
---Note that people who make modified versions of Engine3 are not obligated 
---to grant this special exception for their modified versions; 
---it is their choice whether to do so. The GNU Lesser General Public License 
---gives permission to release a modified version without this exception; 
---this exception also makes it possible to release a modified version 
+--Note that people who make modified versions of Engine3 are not obligated
+--to grant this special exception for their modified versions;
+--it is their choice whether to do so. The GNU Lesser General Public License
+--gives permission to release a modified version without this exception;
+--this exception also makes it possible to release a modified version
 
 
 object_tangible_loot_quest_force_sensitive_theater_datapad = object_tangible_loot_quest_force_sensitive_shared_theater_datapad:new {
 
+       objectMenuComponent = {"cpp", "WaypointDatapadMenuComponent"},
 }
 
 ObjectTemplates:addTemplate(object_tangible_loot_quest_force_sensitive_theater_datapad, "object/tangible/loot/quest/force_sensitive/theater_datapad.iff")
index 277093c..1102c52 100644 (file)
@@ -35,7 +35,8 @@ GoToTheater = Task:new {
        despawnTime = 0,
        activeAreaRadius = 0,
        onFailedSpawn = nil,
-       onSuccessfulSpawn = nil
+       onSuccessfulSpawn = nil,
+       onEnteredActiveArea = nil
 }
 
 -- Setup the active area around the theater.
@@ -66,6 +67,7 @@ function GoToTheater:handleEnteredAreaEvent(pActiveArea, pCreatureObject, nothin
                local storedActiveAreaId = readData(creatureObject:getObjectID() .. self.taskName .. ACTIVE_AREA_ID_STRING)
                ObjectManager.withSceneObject(pActiveArea, function(activeArea)
                        if storedActiveAreaId == activeArea:getObjectID() then
+                               Logger:log("Player entered active area of " .. self.taskName .. " theater.", LT_INFO)
                                local spawnedObjects = SpawnMobiles.getSpawnedMobiles(pCreatureObject, self.taskName)
                                self:callFunctionIfNotNil(self.onEnteredActiveArea, nil, pCreatureObject, spawnedObjects)
                        end
@@ -99,7 +101,7 @@ function GoToTheater:taskStart(pCreatureObject)
                                                if waypointId ~= nil then
                                                        writeData(creatureObject:getObjectID() .. self.taskName .. WAYPOINT_ID_STRING, waypointId)
                                                        createEvent(self.despawnTime, "handleDespawnTheater", self.taskName, pCreatureObject)
-                                                       self:callFunctionIfNotNil(self.onSuccessfulSpawn, nil, pCreatureObject)
+                                                       self:callFunctionIfNotNil(self.onSuccessfulSpawn, nil, pCreatureObject, spawnedMobilesList)
                                                        return true
                                                end
                                        end
index 310cada..1f095ea 100644 (file)
@@ -236,7 +236,7 @@ describe("GoToTheater", function()
                                                        it("Should call the onSuccessfulSpawn function.", function()
                                                                testGoToTheater:start(pCreatureObject)
 
-                                                               assert.spy(testGoToTheater.onSuccessfulSpawn).was.called_with(testGoToTheater, pCreatureObject)
+                                                               assert.spy(testGoToTheater.onSuccessfulSpawn).was.called_with(testGoToTheater, pCreatureObject, spawnedMobilesList)
                                                        end)
 
                                                        it("Should not finish the task.", function()