FILES ----- [NEW] behaviors\npc\quests\quest-collect_fine-notification.behavior [NEW] behaviors\npc\quests\quest-return_stolen-idle.behavior [NEW] behaviors\npc\quests\quest-return_stolen-notification.behavior damage\firebarrier.damage damage\icebarrier.damage damage\poisonbarrier.damage dialog\quest.config items\active\weapons\melee\altabilities\broadsword\bladecharge\bladecharge.altability items\active\weapons\melee\altabilities\broadsword\bladecharge\bladecharge.lua items\active\weapons\melee\altabilities\broadsword\giantsword\giantsword.altability items\active\weapons\melee\altabilities\broadsword\traildash\traildash.altability items\active\weapons\melee\altabilities\broadsword\traildash\traildash.lua items\active\weapons\melee\altabilities\broadsword\travelingslash\travelingslash.altability items\active\weapons\melee\altabilities\generic\blinkslash\blinkslash.altability [NEW] items\active\weapons\melee\altabilities\hammer\elementalpillar\elementalpillar.altability [NEW] items\active\weapons\melee\altabilities\hammer\elementalpillar\elementalpillar.lua items\active\weapons\melee\altabilities\spear\elementalspin\elementalspin.altability items\active\weapons\melee\altabilities\spear\spin\spin.altability items\active\weapons\melee\hammer\rarehammer.activeitem items\active\weapons\melee\spear\rarespear.activeitem [NEW] items\active\weapons\ranged\altabilities\vacuumsphere\vacuumsphere.altability items\active\weapons\ranged\shotgun\rareshotgun.activeitem items\armors\human\human-tier2\humantier2.head items\armors\human\human-tier2\humantier2.legs items\buildscripts\buildweapon.lua monsters\flying\smallflying\smallflying.monstertype [NEW] projectiles\pillar\default.frames [NEW] projectiles\pillar\electricpillar.png [NEW] projectiles\pillar\electricpillar.projectile [NEW] projectiles\pillar\firepillar.png [NEW] projectiles\pillar\firepillar.projectile [NEW] projectiles\pillar\icepillar.png [NEW] projectiles\pillar\icepillar.projectile [NEW] projectiles\pillar\pillarspawner.projectile [NEW] projectiles\pillar\poisonpillar.png [NEW] projectiles\pillar\poisonpillar.projectile [NEW] projectiles\unsorted\vacuumsphere\icon.png [NEW] projectiles\unsorted\vacuumsphere\vacuumsphere.frames [NEW] projectiles\unsorted\vacuumsphere\vacuumsphere.png [NEW] projectiles\unsorted\vacuumsphere\vacuumsphere.projectile [NEW] projectiles\unsorted\vacuumsphere\vacuumsphereprimer.frames [NEW] projectiles\unsorted\vacuumsphere\vacuumsphereprimer.png [NEW] projectiles\unsorted\vacuumsphere\vacuumsphereprimer.projectile quests\generated\comfort.config quests\generated\protection.config quests\generated\subquests.config quests\generated\comfort\add_object_to_house.questtemplate quests\generated\protection\collect_fine.questtemplate quests\generated\subquests\bribe.questtemplate quests\generated\subquests\build_home.questtemplate quests\generated\subquests\farming.questtemplate quests\generated\subquests\fetch.questtemplate quests\generated\subquests\gift.questtemplate [NEW] quests\generated\subquests\return_stolen.questtemplate quests\generated\subquests\steal.questtemplate quests\scripts\generated\collect_fine.lua quests\scripts\generated\common.lua [NEW] quests\scripts\generated\return_stolen.lua scripts\relationships.lua scripts\actions\quests.lua scripts\quest\participant.lua scripts\questgen\generator.lua scripts\questgen\predicands.lua scripts\questgen\relations.lua sfx\melee\charge_full_swing2.ogg sfx\melee\charge_full_swing3.ogg sfx\melee\charge_full_swing4.ogg [NEW] sfx\melee\charge_traildash4.ogg sfx\melee\charge_up15.ogg sfx\melee\spear_twirl_loop.ogg sfx\melee\travelingslash_electric4.ogg sfx\melee\travelingslash_electric5.ogg sfx\melee\travelingslash_electric6.ogg sfx\melee\travelingslash_electric7.ogg sfx\melee\travelingslash_fire2.ogg DIFFS ----- damage\firebarrier.damage 2a3,6 > "damageNumberParticleKind" : { > "hit" : "burningdamagenumber", > "kill" : "burningdamagenumber" > }, damage\icebarrier.damage 2a3,6 > "damageNumberParticleKind" : { > "hit" : "icedamagenumber", > "kill" : "icedamagenumber" > }, damage\poisonbarrier.damage 2a3,6 > "damageNumberParticleKind" : { > "hit" : "poisondamagenumber", > "kill" : "poisondamagenumber" > }, dialog\quest.config 60a61,80 > }, > > "return_stolen" : { > "objectTaken" : { > "default" : { > "default" : [ > "I assure you, that was acquired legally!" > ] > } > } > }, > > "collect_fine" : { > "fineCollected" : { > "default" : { > "default" : [ > "Fine, fine, I'll pay the fine. Tell it's a fair cop." > ] > } > } items\active\weapons\melee\altabilities\broadsword\bladecharge\bladecharge.altability 21a22 > "persistentSound" : "/sfx/melee/charge_full_hold1.ogg", 27a29,32 > }, > "sounds" : { > // "chargedSwing" : [ "/sfx/melee/swing_broadsword.ogg" ] > "chargedSwing" : [ "/sfx/melee/charge_full_swing3.ogg" ] items\active\weapons\melee\altabilities\broadsword\bladecharge\bladecharge.lua 52c52 < animator.playSound("fire") --- > animator.playSound("chargedSwing") items\active\weapons\melee\altabilities\broadsword\giantsword\giantsword.altability 47c47,50 < "transition": "idle" --- > "transition": "idle", > "properties" : { > "immediateSound" : "/sfx/melee/charge_full_swing1.ogg" > } 169c172 < "damageSourceKind" : "broadsword", --- > "damageSourceKind" : "broadsword", items\active\weapons\melee\altabilities\broadsword\traildash\traildash.altability 51,56c51,59 < "trailDashCharge" : [ "/sfx/melee/charge_traildash3.ogg" ], < "trailDashFire" : [ "/sfx/melee/travelingslash_electric1.ogg", "/sfx/melee/travelingslash_electric2.ogg", "/sfx/melee/travelingslash_electric3.ogg" ] < // FIRE "trailDashFire" : [ "/sfx/melee/travelingslash_fire3.ogg" ] < // ICE "trailDashFire" : [ "/sfx/melee/travelingslash_ice4.ogg" ] < // ELECTRIC "trailDashFire" : [ "/sfx/melee/travelingslash_electric1.ogg", "/sfx/melee/travelingslash_electric2.ogg", "/sfx/melee/travelingslash_electric3.ogg" ] < // POISON "trailDashFire" : [ "/sfx/melee/travelingslash_poison3.ogg" ] --- > "fireTrailDashCharge" : [ "/sfx/melee/charge_traildash3.ogg" ], > "iceTrailDashCharge" : [ "/sfx/melee/charge_traildash3.ogg" ], > "electricTrailDashCharge" : [ "/sfx/melee/charge_traildash3.ogg" ], > "poisonTrailDashCharge" : [ "/sfx/melee/charge_traildash3.ogg" ], > > "fireTrailDashFire" : [ "/sfx/melee/travelingslash_fire3.ogg" ], > "iceTrailDashFire" : [ "/sfx/melee/travelingslash_ice4.ogg" ], > "electricTrailDashFire" : [ "/sfx/melee/travelingslash_electric1.ogg", "/sfx/melee/travelingslash_electric2.ogg", "/sfx/melee/travelingslash_electric3.ogg" ], > "poisonTrailDashFire" : [ "/sfx/melee/travelingslash_poison3.ogg" ] items\active\weapons\melee\altabilities\broadsword\traildash\traildash.lua 29c29 < animator.playSound("trailDashCharge") --- > animator.playSound(self.weapon.elementalType.."TrailDashCharge") 39c39 < animator.playSound("trailDashFire") --- > animator.playSound(self.weapon.elementalType.."TrailDashFire") items\active\weapons\melee\altabilities\broadsword\travelingslash\travelingslash.altability 5,8c5,9 < "fireTravelSlash" : [ "/sfx/gun/plasma_sniper1.ogg" ], < "iceTravelSlash" : [ "/sfx/gun/plasma_sniper1.ogg" ], < "electricTravelSlash" : [ "/sfx/gun/plasma_sniper1.ogg" ], < "poisonTravelSlash" : [ "/sfx/gun/plasma_sniper1.ogg" ] --- > "fireTravelSlash" : [ "/sfx/melee/travelingslash_fire1.ogg" ], > "iceTravelSlash" : [ "/sfx/melee/travelingslash_ice2.ogg" ], > // "electricTravelSlash" : [ "/sfx/melee/travelingslash_electric1.ogg", "/sfx/melee/travelingslash_electric2.ogg", "/sfx/melee/travelingslash_electric3.ogg" ], > "electricTravelSlash" : [ "/sfx/melee/travelingslash_electric4.ogg" ], > "poisonTravelSlash" : [ "/sfx/melee/travelingslash_poison3.ogg" ] items\active\weapons\melee\altabilities\generic\blinkslash\blinkslash.altability 57a58 > "damageSourceKind" : "broadsword", items\active\weapons\melee\altabilities\spear\elementalspin\elementalspin.altability 14a15 > //"immediateSound" : "/sfx/melee/spear_twirl_start.ogg", 48,51c49,52 < "fireSpinFire" : ["/sfx/melee/swing_spear_fire3.ogg" ], < "iceSpinFire" : ["/sfx/melee/swing_spear_ice3.ogg" ], < "electricSpinFire" : ["/sfx/melee/swing_spear_electric3.ogg" ], < "poisonSpinFire" : ["/sfx/melee/swing_spear_poison3.ogg" ] --- > "fireSpinFire" : ["/sfx/melee/travelingslash_fire2.ogg" ], > "iceSpinFire" : ["/sfx/melee/travelingslash_ice2.ogg" ], > "electricSpinFire" : [ "/sfx/melee/travelingslash_electric7.ogg" ], > "poisonSpinFire" : ["/sfx/melee/travelingslash_poison1.ogg" ] 128c129 < "spinRate" : -2000, --- > "spinRate" : -1750, items\active\weapons\melee\altabilities\spear\spin\spin.altability 13c13,17 < "cycle" : 0.5 --- > "cycle" : 0.5, > "properties" : { > //"immediateSound" : "/sfx/melee/spear_twirl_start.ogg", > "persistentSound" : "/sfx/melee/spear_twirl_loop.ogg" > } 61c65 < "spinRate" : -1200, --- > "spinRate" : -1750, items\active\weapons\melee\hammer\rarehammer.activeitem 127,128c127,129 < //"/items/active/weapons/melee/altabilities/hammer/shockwave/shockwave.altability", < "/items/active/weapons/melee/altabilities/hammer/elementalaura/elementalaura.altability" --- > // "/items/active/weapons/melee/altabilities/hammer/shockwave/shockwave.altability", > // "/items/active/weapons/melee/altabilities/hammer/elementalaura/elementalaura.altability", > "/items/active/weapons/melee/altabilities/hammer/elementalpillar/elementalpillar.altability" items\active\weapons\melee\spear\rarespear.activeitem 117c117 < "/items/active/weapons/melee/altabilities/generic/blinkexplosion/blinkexplosion.altability", --- > //"/items/active/weapons/melee/altabilities/generic/blinkexplosion/blinkexplosion.altability", 119c119 < "/items/active/weapons/melee/altabilities/spear/elementalspin/elementalspin.altability", --- > //"/items/active/weapons/melee/altabilities/spear/elementalspin/elementalspin.altability", items\active\weapons\ranged\shotgun\rareshotgun.activeitem 105c105,107 < "altAbilities" : [ ], --- > "altAbilities" : [ > "/items/active/weapons/ranged/altabilities/vacuumsphere/vacuumsphere.altability" > ], items\armors\human\human-tier2\humantier2.head 37a38,39 > "questTags" : [ "steelarmor" ], > items\armors\human\human-tier2\humantier2.legs 36a37,38 > "questTags" : [ "steelarmor" ], > items\buildscripts\buildweapon.lua 130a131,133 > if path(config, "altAbility", "damageConfig", "damageSourceKind") and parameters.elementalType then > config.altAbility.damageConfig.damageSourceKind = string.gsub(config.altAbility.damageConfig.damageSourceKind, "", parameters.elementalType) > end monsters\flying\smallflying\smallflying.monstertype 55,56d54 < "bodyMaterialKind" : "organic", < quests\generated\comfort.config 9a10,12 > }, > "extraRewards" : { > "type" : "itemList" 16a20,23 > ["itemList", "extraRewards", "money", "objectPrice"], > ["itemName", "money", {"literal":"money"}], > ["price", "object", "objectPrice"], > quests\generated\protection.config 15a16 > "templateId" : "collect_fine.generated", 23c24,30 < "behaviorOverrides" : [ { "type" : "flee", "target" : "player" } ], --- > "behaviorOverrides" : [ > { > "type" : "notification", > "behavior" : { "name" : "quest-collect_fine-notification" } > }, > { "type" : "flee", "target" : "player" } > ], 42d48 < "minLength": 2, quests\generated\subquests.config 6a7,9 > }, > "extraRewards" : { > "type" : "itemList" 16c19,20 < "output" : "fetchedItems" --- > "output" : "fetchedItems", > "extraMerge" : [ "extraRewards" ] 19a24,27 > ["itemList", "extraRewards", "money", "itemPrice"], > ["itemName", "money", {"literal":"money"}], > ["price", "item", "itemPrice"], > 41a50,52 > }, > "extraRewards" : { > "type" : "itemList" 58a70,73 > ["itemList", "extraRewards", "money", "itemPrice"], > ["itemName", "money", {"literal":"money"}], > ["price", "objectItem", "itemPrice"], > 74c89 < ["stolenFrom", "victim", "objectItem"], --- > ["stolen", "victim", "questGiver", "objectItem"], 81c96 < ["stolenFrom", "victim", "objectItem"] --- > ["stolen", "victim", "questGiver", "objectItem"] 129,139d143 < //"monsterLoot" : { < // // TODO < // "preconditions" : [ < // ["isMonsterLoot", "monsterType", "item"], < // ["monsterSpawnsOnWorld", "monsterType"] < // ], < // "postconditions" : [ < // ["owns", "player", "item", "count"] < // ] < //}, < 147a152,154 > }, > "extraRewards" : { > "type" : "itemList" 157c164 < "extraMerge" : ["seedList"] --- > "extraMerge" : ["seedList", "extraRewards"] 160a168,171 > ["itemList", "extraRewards", "money", "itemPrice"], > ["itemName", "money", {"literal":"money"}], > ["price", "cropList", "itemPrice"], > 210,217d220 < "escort" : { < // TODO < "preconditions" : [], < "postconditions" : [ < ["at", "questGiver", "location"] < ] < }, < 228a232,234 > }, > "extraRewards" : { > "type" : "itemList" 234a241,246 > ["itemList", "extraRewards", "money", "rewardMoney"], > ["itemName", "money", {"literal":"money"}], > ["price", "extraPiece1", "itemPrice1"], > ["price", "extraPiece2", "itemPrice2"], > ["+", "itemPrice1", "itemPrice2", "rewardMoney"], > 260c272,314 < // TODO --- > "templateId" : "return_stolen.generated", > "parameters" : { > "victimDeed" : { > "type" : "entity" > }, > "victim" : { > "type" : "entity" > }, > "thiefDeed" : { > "type" : "entity" > }, > "thief" : { > "type" : "entity" > }, > "item" : { > "type" : "item" > }, > "object" : { > "type" : "entity" > }, > "extraRewards" : { > "type" : "itemList" > } > }, > "participants" : { > "victim" : { > "critical" : true > }, > "victimDeed" : { > "critical" : true > }, > "thief" : { > "behaviorOverrides" : [ > { "type" : "idle", "target" : "object", "behavior" : { "name" : "quest-return_stolen-idle" } }, > { "type" : "notification", "behavior" : { "name" : "quest-return_stolen-notification" } } > ], > "critical" : true > }, > "thiefDeed" : { > "critical" : true > } > }, > 261a316,319 > ["itemList", "extraRewards", "money", "itemPrice"], > ["itemName", "money", {"literal":"money"}], > ["price", "item", "itemPrice"], > 263,266c321,323 < ["owns", "thief", "item", "thiefCount"], < ["stolenFrom", "victim", "item"], < ["+", "newThiefCount", 1, "thiefCount"], < ["+", "victimCount", 1, "newVictimCount"], --- > ["hasTenant", "thiefDeed", "thief"], > ["hasTenant", "victimDeed", "victim"], > ["stolen", "victim", "thief", "item"], 271c328 < ["objectExists", "item"] --- > ["getStealableObjectEntity", "thiefDeed", "item", "object"] 274,278c331,335 < ["!owns", "thief", "item", "thiefCount"], < ["owns", "thief", "item", "newThiefCount"], < ["!owns", "victim", "item", "victimCount"], < ["owns", "victim", "item", "newVictimCount"], < ["!stolenFrom", "victim", "item"], --- > ["!owns", "thiefDeed", "item", 1], > ["owns", "thiefDeed", "item", 0], > ["!owns", "victimDeed", "item", 0], > ["owns", "victimDeed", "item", 1], > ["!stolen", "victim", "thief", "item"], 280,281c337,338 < ["!criminal", "thief"], < ["likes", "victim", "questGiver"] --- > ["likes", "victim", "questGiver"], > ["trusts", "victim", "questGiver"] 284,285d340 < ["owns", "victim", "item", "newVictimCount"], < ["!likes", "thief", "questGiver"], 330a386,388 > }, > "extraRewards" : { > "type" : "itemList" 344a403,406 > ["itemList", "extraRewards", "money", "itemPrice"], > ["itemName", "money", {"literal":"money"}], > ["price", "gift", "itemPrice"], > 371a434,436 > }, > "extraRewards" : { > "type" : "itemList" 385a451,454 > ["itemList", "extraRewards", "money", "itemPrice"], > ["itemName", "money", {"literal":"money"}], > ["price", "gift", "itemPrice"], > 530c599 < "protect" : { --- > /*"protect" : { 545c614 < }, --- > }, */ quests\generated\comfort\add_object_to_house.questtemplate 17a18 > "rewardParameters" : [ "extraRewards" ], quests\generated\protection\collect_fine.questtemplate 4,6c4,12 < "text" : " has been caught breaking the law and has evaded our attempts to collect the fines due. If you can convince to pay, I'll give you a portion of the money as a reward.", < "completionText" : "Great work! Here's your reward.", < "failureText" : "I was unable to catch the criminal .", --- > "goalText" : "^orange; has been caught breaking the law and must pay a fine.^white;\n", > "text" : { > "default" : "Convince ^green;^white; to pay, and I'll give you a portion of the fine as a reward.", > "last" : "Finally, convince ^green;^white; to pay, and I'll give you a portion of the fine as a reward." > }, > "completionText" : { > "default" : "Great work! I wish others cared as much about upholding the law as you.\nHere's your cut." > }, > "failureText" : "I was unable to collect the fine from criminal .", 9c15 < "moneyRange" : [10, 50], --- > "moneyRange" : [100, 150], quests\generated\subquests\bribe.questtemplate 20a21 > "rewardParameters" : [ "extraRewards" ], quests\generated\subquests\build_home.questtemplate 18a19 > "rewardParameters" : [ "extraRewards" ], quests\generated\subquests\farming.questtemplate 18a19 > "rewardParameters" : [ "extraRewards" ], quests\generated\subquests\fetch.questtemplate 18a19 > "rewardParameters" : [ "extraRewards" ], quests\generated\subquests\gift.questtemplate 20a21 > "rewardParameters" : [ "extraRewards" ], quests\generated\subquests\steal.questtemplate 19a20 > "rewardParameters" : [ "extraRewards" ], 26d26 < "portraitParameter" : "victim", quests\scripts\generated\collect_fine.lua 9c9,15 < notifyNpc(targetUniqueId, "finecollected") --- > notifyNpc(targetUniqueId, "collectFine") > self.questClient:setEventHandler({"target", "fineCollected"}, onFineCollected) > end > end > > function onFineCollected(targetUniqueId, interactorEntityId) > if interactorEntityId == entity.id() then quests\scripts\generated\common.lua 77,78c77,81 < function notifyNpc(uniqueId, notificationType) < self.outbox:sendMessage(uniqueId, "notify", { --- > function notifyNpc(name, notificationType) > if quest.parameters()[name] and quest.parameters()[name].uniqueId then > name = quest.parameters()[name].uniqueId > end > self.outbox:sendMessage(name, "notify", { scripts\relationships.lua 0a1,2 > require("/scripts/util.lua") > 44,50c46,48 < function setStolenItem(item, wasStolen) < storage.stolenItems = storage.stolenItems or {} < if wasStolen then < storage.stolenItems[item] = true < else < storage.stolenItems[item] = nil < end --- > function getStolenTable() > storage.stolen = storage.stolen or { items = {}, thieves = {} } > return storage.stolen 53,54c51,52 < function isStolenItem(item) < return storage.stolenItems[item] or false --- > function getStolenItems() > return util.tableKeys(getStolenTable().items) 57,58c55,87 < function getStolenItems() < return util.tableKeys(storage.stolenItems or {}) --- > function getThievesForStolenItem(itemName) > local stolen = getStolenTable() > if not stolen.items[itemName] then stolen.items[itemName] = {} end > return stolen.items[itemName] > end > > function getStolenItemsForThief(uniqueId) > local stolen = getStolenTable() > if not stolen.thieves[uniqueId] then stolen.thieves[uniqueId] = {} end > return stolen.thieves[uniqueId] > end > > function setStolen(thiefUniqueId, itemName) > table.insert(getThievesForStolenItem(itemName), thiefUniqueId) > table.insert(getStolenItemsForThief(thiefUniqueId), itemName) > end > > function unsetStolen(thiefUniqueId, itemName) > local thieves = getThievesForStolenItem(itemName) > local thiefIndex = contains(thieves, thiefUniqueId) > if thiefIndex then > table.remove(thieves, thiefIndex) > end > > local items = getStolenItemsForThief(thiefUniqueId) > local itemIndex = contains(items, itemName) > if itemIndex then > table.remove(items, itemIndex) > end > end > > function isStolen(thiefUniqueId, itemName) > return contains(getThievesForStolenItem(itemName), thiefUniqueId) scripts\actions\quests.lua 23c23,25 < return root.itemConfig(param.item).itemName --- > local itemConfig = root.itemConfig(param.item) > local name = itemConfig.parameters.shortdescription or itemConfig.config.shortdescription > return name scripts\quest\participant.lua 249,250c249,252 < elseif type == "setStolenItem" then < setStolenItem(table.unpack(arguments)) --- > elseif type == "setStolen" then > setStolen(table.unpack(arguments)) > elseif type == "unsetStolen" then > unsetStolen(table.unpack(arguments)) scripts\questgen\generator.lua 177c177 < if not endGoal:preconditions():isGround() then return nil end --- > if not endGoal:isGround() then return nil end 190c190 < if not finalQuest:preconditions():isGround() then return nil end --- > if not finalQuest:isGround() then return nil end scripts\questgen\predicands.lua 109a110,114 > function QuestPredicands.Item:price() > local itemConfig = root.itemConfig(self.itemName) > return itemConfig.config.price or 0 > end > 178a184,192 > end > > function QuestPredicands.ItemList:price() > local price = 0 > for itemName, count in pairs(self.items) do > local itemConfig = root.itemConfig({ name = itemName, count = count }) > price = price + (itemConfig.config.price or 0) > end > return price scripts\questgen\relations.lua 31a32 > if self.negated then return Relation.empty end 39c40,50 < [case(2, Entity, Item, Nil)] = function (self, deed, item) --- > [case(2, Entity, Item, NonNil)] = function (self, deed, item, count) > local objects = deed:callScript("getOwnedObjectNames") or {} > local results = {} > if xor(self.negated, (objects[item.itemName] or 0) == count) then > return {{deed, item, count}} > end > return Relation.empty > end, > > [case(3, Entity, Item, Nil)] = function (self, deed, item) > if self.negated then return Relation.some end 44,45d54 < else < return {{deed, item, 0}} 47c56 < return results --- > return {{deed, item, 0}} 50c59,60 < [case(3, Entity, Nil, Nil)] = function (self, deed) --- > [case(4, Entity, Nil, Nil)] = function (self, deed) > if self.negated then return Relation.some end 59c69,70 < [case(4, Nil, Item, NonNil)] = function (self, _, object, count) --- > [case(5, Nil, Item, NonNil)] = function (self, _, object, count) > if self.negated then return Relation.some end 70c81,82 < [case(5, Nil, Item, Nil)] = function (self, _, object, _) --- > [case(6, Nil, Item, Nil)] = function (self, _, object, _) > if self.negated then return Relation.some end 80c92 < [case(6, Nil, ItemTag, Any)] = Relation.empty, --- > [case(7, Nil, ItemTag, Any)] = Relation.empty, 279c291 < QuestRelations.stolenFrom = defineRelation("stolenFrom", false) { --- > QuestRelations.stolen = defineRelation("stolen", false) { 281,284c293,309 < [case(1, Entity, Item)] = function (self, entity, item) < if xor(self.negated, entity:callScript("isStolenItem", item.itemName)) then < return {{entity, item}} < else --- > [case(1, Entity, Entity, Item)] = function (self, victim, thief, item) > if not thief:uniqueId() then > if self.negated then > return {victim, thief, item} > else > return Relation.empty > end > end > if xor(self.negated, victim:callScript("isStolen", thief:uniqueId(), item.itemName)) then > return {{victim, thief, item}} > end > return Relation.empty > end, > > [case(2, Entity, Entity, Nil)] = function (self, victim, thief) > if self.negated then return Relation.some end > if not thief:uniqueId() then 286a312,315 > local items = victim:callScript("getStolenItemsForThief", thief:uniqueId()) > return util.map(items, function(itemName) > return {victim, thief, Item.new(itemName)} > end) 289c318 < [case(2, Entity, Nil)] = function (self, entity) --- > [case(3, Entity, Nil, Item)] = function (self, victim, _, item) 291,292c320,322 < return util.map(entity:callScript("getStolenItems") or {}, function (itemName) < return {entity, Item.new(itemName)} --- > local thieves = victim:callScript("getThievesForStolenItem", item.itemName) > return util.map(thieves, function(thief) > return {victim, self.context:entity(thief), item} 296c326,385 < [case(3, Nil, Nil)] = Relation.some, --- > [case(4, Entity, Nil, Nil)] = function (self, victim) > if self.negated then return Relation.some end > local stolenItems = victim:callScript("getStolenItems") > local result = {} > for _, itemName in pairs(stolenItems) do > local item = Item.new(itemName) > for _, thief in pairs(victim:callScript("getThievesForStolenItem", itemName)) do > result[#result+1] = {victim, self.context:entity(thief), item} > end > end > return result > end, > > [case(5, Nil, Entity, Item)] = function (self, _, thief, item) > if self.negated then return Relation.some end > local result = {} > for _,victim in ipairs(util.take(5, shuffled(self.context:entitiesByType()["npc"]))) do > if contains(victim:callScript("getThievesForStolenItem", item.itemName), thief:uniqueId()) then > result[#result+1] = {victim, thief, item} > end > end > return result > end, > > [case(6, Nil, Entity, Nil)] = function (self, _, thief) > if self.negated then return Relation.some end > if not thief:uniqueId() then return Relation.empty end > local result = {} > for _,victim in ipairs(util.take(5, shuffled(self.context:entitiesByType()["npc"]))) do > for _, itemName in pairs(victim:callScript("getStolenItemsForThief", thief:uniqueId())) do > result[#result+1] = {victim, thief, Item.new(itemName)} > end > end > return result > end, > > [case(7, Nil, Nil, Item)] = function (self, _, _, item) > if self.negated then return Relation.some end > local result = {} > for _,victim in ipairs(util.take(5, shuffled(self.context:entitiesByType()["npc"]))) do > for _, thiefUniqueId in pairs(victim:callScript("getThievesForStolenItem", item.itemName)) do > result[#result+1] = {victim, self.context:entity(thiefUniqueId), item} > end > end > return result > end, > > [case(8, Nil, Nil, Nil)] = function (self) > if self.negated then return Relation.some end > local result = {} > for _,victim in ipairs(util.take(5, shuffled(self.context:entitiesByType()["npc"]))) do > for _, itemName in pairs(victim:callScript("getStolenItems")) do > local item = Item.new(itemName) > for _, thief in pairs(victim:callScript("getThievesForStolenItem", itemName)) do > result[#result+1] = {victim, self.context:entity(thief), item} > end > end > end > return result > end, 300c389,395 < npcStateDeltas = npcStateDeltaMethod(function (self, npc, item) --- > > npcStateDeltas = npcStateDeltaMethod(function (self, npc, thief, item) > local thiefUniqueId = thief:uniqueId() > local deltaName = "setStolen" > if self.negated then > deltaName = "unsetStolen" > end 303,304c398,399 < type = "setStolenItem", < arguments = {item.itemName, not self.negated} --- > type = deltaName, > arguments = {thiefUniqueId, item.itemName} 611a707,736 > default = Relation.empty > } > > QuestRelations.price = defineQueryRelation("price", true) { > [case(1, Item, NonNil)] = function (self, item, price) > if xor(self.negated, price == item:price()) then > return {{item, price}} > end > return Relation.empty > end, > > [case(2, ItemList, NonNil)] = function (self, itemList, price) > if xor(self.negated, price == itemList:price()) then > return {{itemList, price}} > end > return Relation.empty > end, > > [case(3, Item, Nil)] = function (self, item) > if self.negated then return Relation.some end > return {{item, item:price()}} > end, > > [case(4, ItemList, Nil)] = function (self, itemList) > if self.negated then return Relation.some end > return {{itemList, itemList:price()}} > end, > > [case(5, Nil, Any)] = Relation.some, >