diff --git a/_build/Script objects.txt b/_build/Script objects.txt new file mode 100644 index 00000000..cc8842bb --- /dev/null +++ b/_build/Script objects.txt @@ -0,0 +1,100 @@ +action.* +activator.* +activemagiceffect.* +actor.* +actorbase.* +actorvalueinfo.* +alias.* +ammo.* +apparatus.* +armor.* +armoraddon.* +art.* +associationtype.* +book.* +camera.* +cell.* +class.* +colorcomponent.* +colorform.* +combatstyle.* +constructibleobject.* +container.* +debug.* +defaultobjectmanager.* +door.* +effectshader.* +enchantment.* +encounterzone.* +equipslot.* +explosion.* +faction.* +flora.* +form.* +formlist.* +formtype.* +furniture.* +game.* +gamedata.* +globalvariable.* +hazard.* +headpart.* +idle.* +imagespacemodifier.* +impactdataset.* +ingredient.* +input.* +isequippedarmortype.* +key.* +keyword.* +leveledactor.* +leveleditem.* +leveledspell.* +light.* +location.* +locationalias.* +locationreftype.* +magiceffect.* +math.* +message.* +miscobject.* +modevent.* +musictype.* +netimmerse.* +objectreference.* +outfit.* +package.* +perk.* +potion.* +projectile.* +quest.* +race.* +referencealias.* +skse.* +scene.* +scroll.* +shaderparticlegeometry.* +shout.* +soulgem.* +sound.* +soundcategory.* +sounddescriptor.* +spawnertask.* +spell.* +static.* +stringutil.* +talkingactivator.* +textureset.* +topic.* +topicinfo.* +treeobject.* +ui.* +uicallback.* +utility.* +visualeffect.* +voicetype.* +weapon.* +weather.* +wordofpower.* +worldspace.* +wornobject.* diff --git a/_build/Used Skyrim scripts.txt b/_build/Used Skyrim scripts.txt new file mode 100644 index 00000000..75acdbbb --- /dev/null +++ b/_build/Used Skyrim scripts.txt @@ -0,0 +1,205 @@ +abforswornbriarheartscript.* +achievementsscript.* +activateselfoncombatbegin.* +atronachfrostscript.* +barreddoor.* +batteringtrap.* +beehivehavokonhit.* +blackreachdoorscript.* +blacksmithforge01.* +bladetrap.* +boundboweffectscript.* +briarheartingredientscript.* +carryactorscript.* +carryfurniturescript.* +companionshousekeepingscript.* +companionsradiantquest.* +companionsstoryquest.* +cr04questscript.* +craftingactivatelinker.* +crimeguardsscript.* +critterspawn01.* +curediseasescript.* +cwalliesscript.* +cwcampaignpollformissionacceptscript.* +cwcampaignscript.* +cwcatapultoffscreenfirecontrolscript.* +cwcatapultscript.* +cwcatapultstrikescript.* +cwreinforcementcontrollerscript.* +cwscript.* +cwsiegescript.* +cwthreatcombatbarksscript.* +darkbrotherhood.* +darksanctuarydialoguescript.* +darttrap.* +defaultactivatelinkdooncescript.* +defaultactselfonenteronleave.* +defaultblockactivation.* +defaultblockfolloweractivation.* +defaultbuttonscript.* +defaultcastfromlinkontriggerscript.* +defaultdeleteselfonreset.* +defaultdisableexitenableenter.* +defaultdisableonloadaftertrig.* +defaultdisableotherobjectonactivate.* +defaultdisableselfonactivate.* +defaultdwebuttonscript.* +defaultdwegearscript.* +defaultenabledisablelinkedref.* +defaultenablelinkedrefondeath.* +defaultfakenpcloadtrig.* +defaultfireweaponscript.* +defaultforceevaluatepackagetrigger.* +defaultghostscript.* +defaultifaliveplaysoundscript.* +defaultimodareatrig.* +defaultlinkrefstartcombatplayer.* +defaultonenter.* +defaultpillarpuzzlelever.* +defaultpillarpuzzlelevernofurn.* +defaultpillarpuzzlepullbarnofurn.* +defaultplayerenabledisablelinkedref.* +defaultplaysoundatlinkscript.* +defaultprisonerdoorscript.* +defaultpuzzlepillarnofurn.* +defaultpuzzlepillarpullbarnofurn.* +defaultpuzzlepillarscript.* +defaultsetlinkavvar.* +defaultsetmultiavtriggerscript.* +defaultsetstageonenter.* +defaultsetstagetrigscript.* +dialoguefollowerscript.* +dlc2hermaeusmorafacefxscript.* +dlc2miraakcombatmagiclevelingscript.* +dlc2miraakscript.* +dlc2mq05hermaeusmorafxscript.* +dlc2mq06miraakbossbattle.* +dlc2mq06script.* +dlc2mqbosstentaclecontroller.* +dlc2soulstealscript.* +dlc2standingstonescript.* +dlc2tamedragonscript.* +doorbar.* +dragonperchscript.* +dragonpriestactorscript.* +dragontowerwallscript.* +dunarcherpressureplatescript.* +dunarcherquestscript.* +duncgfiretriggerscript.* +dunkagrenzelanimationresetscript.* +dunkarthspirepuzzlemaster.* +dunkatariahscimitarscript.* +dunmiddentorchscript.* +dwepipevalve01script.* +dwespherecenturionportscript.* +dwespidercenturionpipescript.* +dwesteamcenturionstructurescript.* +favordialoguescript.* +flameatronacheffectscript.* +fxbatscaredscript.* +fxbirdfleescript.* +fxchaurusscript.* +fxdragonblooddamagescript.* +fxdraugrmagicscript.* +fxdustdroponactivatescript.* +fxdustdroptrigscript.* +fxdwarvencenturionscript.* +fxdwarvenspherescript.* +fxdwarvenspiderscript.* +fxgreybeardshoutscript.* +fxmg07dogscript.* +fxsetblendvariablescript.* +fxshadowmereemergescript.* +fxskeletonnecroscript.* +fxsovengardescript.* +fxtriggerambfx.* +hangedmanscript.* +hardworkerwoodscript.* +hazardbase.* +helgenrandomsoundscript.* +icewraithparticlesscript.* +itemwithsoudscript.* +magicabsorbfxscript.* +magicattachashpileondeath.* +magicbanishscript.* +magicdispelspellonhitscript.* +magiceffectshaderapply.* +magiceffectshadersonendscript.* +magicimodbasicscript.* +magicimodbeginloopend.* +magicimodonplayerhitscript.* +magicnighteyescript.* +magicplaceactivatorscript.* +magicplayeffectshaderonhitscript.* +magicsetactoralphascript.* +mg08paralysiseffectscript.* +movingtrap.* +mqgreybeardabsorbscript.* +mqkilldragonscript.* +ms10questscript.* +ms11questscript.* +nightingalesecdoorscript.* +noflightabilityscript.* +norlever01script.* +norportcullisscript.* +norpullbar01script.* +norrotatingdoorscript.* +norsarcophagustopanim01script.* +pdbentrancequestscript.* +pf_ambushsleeplinkedref_00048abc.* +pf_carryfirewood_000d97fa.* +pf_dgintimidatespectatorpacka_000aa053.* +pf_dgintimidatespectatorpacka_000aa054.* +physicstraphit.* +playerbookshelfclicktriggerscript.* +playerbookshelfcontainerscript.* +playerbookshelftriggerscript.* +playerpotionrackclicktriggerscript.* +playerpotionracktriggerscript.* +playerwerewolfchangescript.* +pressureplate.* +pressurereleaseplate.* +reanimateashpile.* +resourcefurniturescript.* +resourceobjectsawmillscript.* +resourceobjectscript.* +sayonhitbymagiceffectscript.* +sethirelingrehire.* +shaderparticlegeometryscript.* +silverswordscript.* +skyhavensconcescript.* +speartrap.* +spiderwebanimationsscript.* +spriggancallanimalsaoe.* +sprigganswarmactorscript.* +summontargetfxactivatorscript.* +trapbase.* +trapbear.* +trapdweballista.* +trapdweflamepillar.* +trapdweflamepillarhit.* +trapdwepiston.* +trapfireplate.* +trapgenericeffecthazard.* +traphitbase.* +traplever.* +trapnorplatform.* +trapoilpool.* +trappoisongas.* +trappoisongascough.* +trapriggedrockfall.* +traprockfalleffects.* +trapsoulgemcontroller.* +traptriggerbase.* +traptriggerhinge.* +traptriggertimeinterval.* +tripwire.* +voiceiceformscript.* +voiceobjectscript.* +voicepusheffectscript.* +weaponracktriggerscript.* +webdestructiblescript.* +werewolfchangeeffectscript.* +werewolftransformvisual.* +wifunctionsscript.* diff --git a/scripts/abforswornbriarheartscript.pex b/scripts/abforswornbriarheartscript.pex new file mode 100644 index 00000000..b48e3723 Binary files /dev/null and b/scripts/abforswornbriarheartscript.pex differ diff --git a/scripts/achievementsscript.pex b/scripts/achievementsscript.pex new file mode 100644 index 00000000..4754e2bc Binary files /dev/null and b/scripts/achievementsscript.pex differ diff --git a/scripts/activateselfoncombatbegin.pex b/scripts/activateselfoncombatbegin.pex new file mode 100644 index 00000000..c7e23509 Binary files /dev/null and b/scripts/activateselfoncombatbegin.pex differ diff --git a/scripts/atronachfrostscript.pex b/scripts/atronachfrostscript.pex new file mode 100644 index 00000000..64afa328 Binary files /dev/null and b/scripts/atronachfrostscript.pex differ diff --git a/scripts/barreddoor.pex b/scripts/barreddoor.pex new file mode 100644 index 00000000..0e79a32e Binary files /dev/null and b/scripts/barreddoor.pex differ diff --git a/scripts/batteringtrap.pex b/scripts/batteringtrap.pex new file mode 100644 index 00000000..5ced92ef Binary files /dev/null and b/scripts/batteringtrap.pex differ diff --git a/scripts/beehivehavokonhit.pex b/scripts/beehivehavokonhit.pex new file mode 100644 index 00000000..d3af36a1 Binary files /dev/null and b/scripts/beehivehavokonhit.pex differ diff --git a/scripts/blackreachdoorscript.pex b/scripts/blackreachdoorscript.pex new file mode 100644 index 00000000..bada758f Binary files /dev/null and b/scripts/blackreachdoorscript.pex differ diff --git a/scripts/blacksmithforge01.pex b/scripts/blacksmithforge01.pex new file mode 100644 index 00000000..3fd28cf5 Binary files /dev/null and b/scripts/blacksmithforge01.pex differ diff --git a/scripts/bladetrap.pex b/scripts/bladetrap.pex new file mode 100644 index 00000000..6f89d9cb Binary files /dev/null and b/scripts/bladetrap.pex differ diff --git a/scripts/boundboweffectscript.pex b/scripts/boundboweffectscript.pex new file mode 100644 index 00000000..eaa2d19d Binary files /dev/null and b/scripts/boundboweffectscript.pex differ diff --git a/scripts/briarheartingredientscript.pex b/scripts/briarheartingredientscript.pex new file mode 100644 index 00000000..c207b5c0 Binary files /dev/null and b/scripts/briarheartingredientscript.pex differ diff --git a/scripts/carryactorscript.pex b/scripts/carryactorscript.pex new file mode 100644 index 00000000..373b8918 Binary files /dev/null and b/scripts/carryactorscript.pex differ diff --git a/scripts/carryfurniturescript.pex b/scripts/carryfurniturescript.pex new file mode 100644 index 00000000..3d254ad9 Binary files /dev/null and b/scripts/carryfurniturescript.pex differ diff --git a/scripts/companionshousekeepingscript.pex b/scripts/companionshousekeepingscript.pex new file mode 100644 index 00000000..62fe46e0 Binary files /dev/null and b/scripts/companionshousekeepingscript.pex differ diff --git a/scripts/companionsradiantquest.pex b/scripts/companionsradiantquest.pex new file mode 100644 index 00000000..f361e953 Binary files /dev/null and b/scripts/companionsradiantquest.pex differ diff --git a/scripts/companionsstoryquest.pex b/scripts/companionsstoryquest.pex new file mode 100644 index 00000000..b03e40b6 Binary files /dev/null and b/scripts/companionsstoryquest.pex differ diff --git a/scripts/cr04questscript.pex b/scripts/cr04questscript.pex new file mode 100644 index 00000000..84eb1b3c Binary files /dev/null and b/scripts/cr04questscript.pex differ diff --git a/scripts/craftingactivatelinker.pex b/scripts/craftingactivatelinker.pex new file mode 100644 index 00000000..7b680eb9 Binary files /dev/null and b/scripts/craftingactivatelinker.pex differ diff --git a/scripts/crimeguardsscript.pex b/scripts/crimeguardsscript.pex new file mode 100644 index 00000000..6b4cfd2b Binary files /dev/null and b/scripts/crimeguardsscript.pex differ diff --git a/scripts/critterspawn01.pex b/scripts/critterspawn01.pex new file mode 100644 index 00000000..56fe40b7 Binary files /dev/null and b/scripts/critterspawn01.pex differ diff --git a/scripts/curediseasescript.pex b/scripts/curediseasescript.pex new file mode 100644 index 00000000..d3834960 Binary files /dev/null and b/scripts/curediseasescript.pex differ diff --git a/scripts/cwalliesscript.pex b/scripts/cwalliesscript.pex new file mode 100644 index 00000000..6cfe259f Binary files /dev/null and b/scripts/cwalliesscript.pex differ diff --git a/scripts/cwcampaignpollformissionacceptscript.pex b/scripts/cwcampaignpollformissionacceptscript.pex new file mode 100644 index 00000000..4addcc7d Binary files /dev/null and b/scripts/cwcampaignpollformissionacceptscript.pex differ diff --git a/scripts/cwcampaignscript.pex b/scripts/cwcampaignscript.pex new file mode 100644 index 00000000..e0faf16c Binary files /dev/null and b/scripts/cwcampaignscript.pex differ diff --git a/scripts/cwcatapultoffscreenfirecontrolscript.pex b/scripts/cwcatapultoffscreenfirecontrolscript.pex new file mode 100644 index 00000000..5fbc6376 Binary files /dev/null and b/scripts/cwcatapultoffscreenfirecontrolscript.pex differ diff --git a/scripts/cwcatapultscript.pex b/scripts/cwcatapultscript.pex new file mode 100644 index 00000000..de1d00b4 Binary files /dev/null and b/scripts/cwcatapultscript.pex differ diff --git a/scripts/cwcatapultstrikescript.pex b/scripts/cwcatapultstrikescript.pex new file mode 100644 index 00000000..508683a7 Binary files /dev/null and b/scripts/cwcatapultstrikescript.pex differ diff --git a/scripts/cwreinforcementcontrollerscript.pex b/scripts/cwreinforcementcontrollerscript.pex new file mode 100644 index 00000000..dc8c0830 Binary files /dev/null and b/scripts/cwreinforcementcontrollerscript.pex differ diff --git a/scripts/cwscript.pex b/scripts/cwscript.pex new file mode 100644 index 00000000..fd2110d8 Binary files /dev/null and b/scripts/cwscript.pex differ diff --git a/scripts/cwsiegescript.pex b/scripts/cwsiegescript.pex new file mode 100644 index 00000000..a80111e7 Binary files /dev/null and b/scripts/cwsiegescript.pex differ diff --git a/scripts/cwthreatcombatbarksscript.pex b/scripts/cwthreatcombatbarksscript.pex new file mode 100644 index 00000000..eba08b1a Binary files /dev/null and b/scripts/cwthreatcombatbarksscript.pex differ diff --git a/scripts/darkbrotherhood.pex b/scripts/darkbrotherhood.pex new file mode 100644 index 00000000..8d5b484f Binary files /dev/null and b/scripts/darkbrotherhood.pex differ diff --git a/scripts/darksanctuarydialoguescript.pex b/scripts/darksanctuarydialoguescript.pex new file mode 100644 index 00000000..b6f9a462 Binary files /dev/null and b/scripts/darksanctuarydialoguescript.pex differ diff --git a/scripts/darttrap.pex b/scripts/darttrap.pex new file mode 100644 index 00000000..42bde3ea Binary files /dev/null and b/scripts/darttrap.pex differ diff --git a/scripts/defaultactivatelinkdooncescript.pex b/scripts/defaultactivatelinkdooncescript.pex new file mode 100644 index 00000000..5e15020d Binary files /dev/null and b/scripts/defaultactivatelinkdooncescript.pex differ diff --git a/scripts/defaultactselfonenteronleave.pex b/scripts/defaultactselfonenteronleave.pex new file mode 100644 index 00000000..b6d0b016 Binary files /dev/null and b/scripts/defaultactselfonenteronleave.pex differ diff --git a/scripts/defaultblockactivation.pex b/scripts/defaultblockactivation.pex new file mode 100644 index 00000000..db162dbe Binary files /dev/null and b/scripts/defaultblockactivation.pex differ diff --git a/scripts/defaultblockfolloweractivation.pex b/scripts/defaultblockfolloweractivation.pex new file mode 100644 index 00000000..9ca0501c Binary files /dev/null and b/scripts/defaultblockfolloweractivation.pex differ diff --git a/scripts/defaultbuttonscript.pex b/scripts/defaultbuttonscript.pex new file mode 100644 index 00000000..4604214c Binary files /dev/null and b/scripts/defaultbuttonscript.pex differ diff --git a/scripts/defaultcastfromlinkontriggerscript.pex b/scripts/defaultcastfromlinkontriggerscript.pex new file mode 100644 index 00000000..527ff013 Binary files /dev/null and b/scripts/defaultcastfromlinkontriggerscript.pex differ diff --git a/scripts/defaultdeleteselfonreset.pex b/scripts/defaultdeleteselfonreset.pex new file mode 100644 index 00000000..3414f590 Binary files /dev/null and b/scripts/defaultdeleteselfonreset.pex differ diff --git a/scripts/defaultdisableexitenableenter.pex b/scripts/defaultdisableexitenableenter.pex new file mode 100644 index 00000000..dc3b8e42 Binary files /dev/null and b/scripts/defaultdisableexitenableenter.pex differ diff --git a/scripts/defaultdisableonloadaftertrig.pex b/scripts/defaultdisableonloadaftertrig.pex new file mode 100644 index 00000000..a3b66f77 Binary files /dev/null and b/scripts/defaultdisableonloadaftertrig.pex differ diff --git a/scripts/defaultdisableotherobjectonactivate.pex b/scripts/defaultdisableotherobjectonactivate.pex new file mode 100644 index 00000000..cfca6c18 Binary files /dev/null and b/scripts/defaultdisableotherobjectonactivate.pex differ diff --git a/scripts/defaultdisableselfonactivate.pex b/scripts/defaultdisableselfonactivate.pex new file mode 100644 index 00000000..866c9fbf Binary files /dev/null and b/scripts/defaultdisableselfonactivate.pex differ diff --git a/scripts/defaultdwebuttonscript.pex b/scripts/defaultdwebuttonscript.pex new file mode 100644 index 00000000..4eac6d96 Binary files /dev/null and b/scripts/defaultdwebuttonscript.pex differ diff --git a/scripts/defaultdwegearscript.pex b/scripts/defaultdwegearscript.pex new file mode 100644 index 00000000..1e176715 Binary files /dev/null and b/scripts/defaultdwegearscript.pex differ diff --git a/scripts/defaultenabledisablelinkedref.pex b/scripts/defaultenabledisablelinkedref.pex new file mode 100644 index 00000000..ac53ca70 Binary files /dev/null and b/scripts/defaultenabledisablelinkedref.pex differ diff --git a/scripts/defaultenablelinkedrefondeath.pex b/scripts/defaultenablelinkedrefondeath.pex new file mode 100644 index 00000000..32d2a8ae Binary files /dev/null and b/scripts/defaultenablelinkedrefondeath.pex differ diff --git a/scripts/defaultfakenpcloadtrig.pex b/scripts/defaultfakenpcloadtrig.pex new file mode 100644 index 00000000..16128fbf Binary files /dev/null and b/scripts/defaultfakenpcloadtrig.pex differ diff --git a/scripts/defaultfireweaponscript.pex b/scripts/defaultfireweaponscript.pex new file mode 100644 index 00000000..c0beac19 Binary files /dev/null and b/scripts/defaultfireweaponscript.pex differ diff --git a/scripts/defaultforceevaluatepackagetrigger.pex b/scripts/defaultforceevaluatepackagetrigger.pex new file mode 100644 index 00000000..91d388ba Binary files /dev/null and b/scripts/defaultforceevaluatepackagetrigger.pex differ diff --git a/scripts/defaultghostscript.pex b/scripts/defaultghostscript.pex new file mode 100644 index 00000000..1879b95e Binary files /dev/null and b/scripts/defaultghostscript.pex differ diff --git a/scripts/defaultifaliveplaysoundscript.pex b/scripts/defaultifaliveplaysoundscript.pex new file mode 100644 index 00000000..8fdc9363 Binary files /dev/null and b/scripts/defaultifaliveplaysoundscript.pex differ diff --git a/scripts/defaultimodareatrig.pex b/scripts/defaultimodareatrig.pex new file mode 100644 index 00000000..054186d7 Binary files /dev/null and b/scripts/defaultimodareatrig.pex differ diff --git a/scripts/defaultlinkrefstartcombatplayer.pex b/scripts/defaultlinkrefstartcombatplayer.pex new file mode 100644 index 00000000..6c96b0b9 Binary files /dev/null and b/scripts/defaultlinkrefstartcombatplayer.pex differ diff --git a/scripts/defaultonenter.pex b/scripts/defaultonenter.pex new file mode 100644 index 00000000..ccd45146 Binary files /dev/null and b/scripts/defaultonenter.pex differ diff --git a/scripts/defaultpillarpuzzlelever.pex b/scripts/defaultpillarpuzzlelever.pex new file mode 100644 index 00000000..f5bfefee Binary files /dev/null and b/scripts/defaultpillarpuzzlelever.pex differ diff --git a/scripts/defaultpillarpuzzlelevernofurn.pex b/scripts/defaultpillarpuzzlelevernofurn.pex new file mode 100644 index 00000000..c6b7ce20 Binary files /dev/null and b/scripts/defaultpillarpuzzlelevernofurn.pex differ diff --git a/scripts/defaultpillarpuzzlepullbarnofurn.pex b/scripts/defaultpillarpuzzlepullbarnofurn.pex new file mode 100644 index 00000000..0482bbd9 Binary files /dev/null and b/scripts/defaultpillarpuzzlepullbarnofurn.pex differ diff --git a/scripts/defaultplayerenabledisablelinkedref.pex b/scripts/defaultplayerenabledisablelinkedref.pex new file mode 100644 index 00000000..74c88eac Binary files /dev/null and b/scripts/defaultplayerenabledisablelinkedref.pex differ diff --git a/scripts/defaultplaysoundatlinkscript.pex b/scripts/defaultplaysoundatlinkscript.pex new file mode 100644 index 00000000..827f9e34 Binary files /dev/null and b/scripts/defaultplaysoundatlinkscript.pex differ diff --git a/scripts/defaultprisonerdoorscript.pex b/scripts/defaultprisonerdoorscript.pex new file mode 100644 index 00000000..a4b40b1b Binary files /dev/null and b/scripts/defaultprisonerdoorscript.pex differ diff --git a/scripts/defaultpuzzlepillarnofurn.pex b/scripts/defaultpuzzlepillarnofurn.pex new file mode 100644 index 00000000..d06ed576 Binary files /dev/null and b/scripts/defaultpuzzlepillarnofurn.pex differ diff --git a/scripts/defaultpuzzlepillarpullbarnofurn.pex b/scripts/defaultpuzzlepillarpullbarnofurn.pex new file mode 100644 index 00000000..7d531212 Binary files /dev/null and b/scripts/defaultpuzzlepillarpullbarnofurn.pex differ diff --git a/scripts/defaultpuzzlepillarscript.pex b/scripts/defaultpuzzlepillarscript.pex new file mode 100644 index 00000000..3668138d Binary files /dev/null and b/scripts/defaultpuzzlepillarscript.pex differ diff --git a/scripts/defaultsetlinkavvar.pex b/scripts/defaultsetlinkavvar.pex new file mode 100644 index 00000000..c336be2b Binary files /dev/null and b/scripts/defaultsetlinkavvar.pex differ diff --git a/scripts/defaultsetmultiavtriggerscript.pex b/scripts/defaultsetmultiavtriggerscript.pex new file mode 100644 index 00000000..7ed776e8 Binary files /dev/null and b/scripts/defaultsetmultiavtriggerscript.pex differ diff --git a/scripts/defaultsetstageonenter.pex b/scripts/defaultsetstageonenter.pex new file mode 100644 index 00000000..a30c2932 Binary files /dev/null and b/scripts/defaultsetstageonenter.pex differ diff --git a/scripts/defaultsetstagetrigscript.pex b/scripts/defaultsetstagetrigscript.pex new file mode 100644 index 00000000..f590876f Binary files /dev/null and b/scripts/defaultsetstagetrigscript.pex differ diff --git a/scripts/dialoguefollowerscript.pex b/scripts/dialoguefollowerscript.pex new file mode 100644 index 00000000..dfa6cf4a Binary files /dev/null and b/scripts/dialoguefollowerscript.pex differ diff --git a/scripts/dlc2hermaeusmorafacefxscript.pex b/scripts/dlc2hermaeusmorafacefxscript.pex new file mode 100644 index 00000000..f7ac1f39 Binary files /dev/null and b/scripts/dlc2hermaeusmorafacefxscript.pex differ diff --git a/scripts/dlc2miraakcombatmagiclevelingscript.pex b/scripts/dlc2miraakcombatmagiclevelingscript.pex new file mode 100644 index 00000000..30a8456d Binary files /dev/null and b/scripts/dlc2miraakcombatmagiclevelingscript.pex differ diff --git a/scripts/dlc2miraakscript.pex b/scripts/dlc2miraakscript.pex new file mode 100644 index 00000000..2ac8f15b Binary files /dev/null and b/scripts/dlc2miraakscript.pex differ diff --git a/scripts/dlc2mq05hermaeusmorafxscript.pex b/scripts/dlc2mq05hermaeusmorafxscript.pex new file mode 100644 index 00000000..0b26895d Binary files /dev/null and b/scripts/dlc2mq05hermaeusmorafxscript.pex differ diff --git a/scripts/dlc2mq06miraakbossbattle.pex b/scripts/dlc2mq06miraakbossbattle.pex new file mode 100644 index 00000000..1159b312 Binary files /dev/null and b/scripts/dlc2mq06miraakbossbattle.pex differ diff --git a/scripts/dlc2mq06script.pex b/scripts/dlc2mq06script.pex new file mode 100644 index 00000000..9e5e4c2b Binary files /dev/null and b/scripts/dlc2mq06script.pex differ diff --git a/scripts/dlc2mqbosstentaclecontroller.pex b/scripts/dlc2mqbosstentaclecontroller.pex new file mode 100644 index 00000000..456ea74a Binary files /dev/null and b/scripts/dlc2mqbosstentaclecontroller.pex differ diff --git a/scripts/dlc2soulstealscript.pex b/scripts/dlc2soulstealscript.pex new file mode 100644 index 00000000..a5a72fd4 Binary files /dev/null and b/scripts/dlc2soulstealscript.pex differ diff --git a/scripts/dlc2standingstonescript.pex b/scripts/dlc2standingstonescript.pex new file mode 100644 index 00000000..b63b6530 Binary files /dev/null and b/scripts/dlc2standingstonescript.pex differ diff --git a/scripts/dlc2tamedragonscript.pex b/scripts/dlc2tamedragonscript.pex new file mode 100644 index 00000000..30f7dae3 Binary files /dev/null and b/scripts/dlc2tamedragonscript.pex differ diff --git a/scripts/doorbar.pex b/scripts/doorbar.pex new file mode 100644 index 00000000..b7f99f9b Binary files /dev/null and b/scripts/doorbar.pex differ diff --git a/scripts/dragonperchscript.pex b/scripts/dragonperchscript.pex new file mode 100644 index 00000000..2f55c23c Binary files /dev/null and b/scripts/dragonperchscript.pex differ diff --git a/scripts/dragonpriestactorscript.pex b/scripts/dragonpriestactorscript.pex new file mode 100644 index 00000000..d94ef7a2 Binary files /dev/null and b/scripts/dragonpriestactorscript.pex differ diff --git a/scripts/dragontowerwallscript.pex b/scripts/dragontowerwallscript.pex new file mode 100644 index 00000000..343f0992 Binary files /dev/null and b/scripts/dragontowerwallscript.pex differ diff --git a/scripts/dunarcherpressureplatescript.pex b/scripts/dunarcherpressureplatescript.pex new file mode 100644 index 00000000..7680018d Binary files /dev/null and b/scripts/dunarcherpressureplatescript.pex differ diff --git a/scripts/dunarcherquestscript.pex b/scripts/dunarcherquestscript.pex new file mode 100644 index 00000000..fb948c52 Binary files /dev/null and b/scripts/dunarcherquestscript.pex differ diff --git a/scripts/duncgfiretriggerscript.pex b/scripts/duncgfiretriggerscript.pex new file mode 100644 index 00000000..fa5ac8c0 Binary files /dev/null and b/scripts/duncgfiretriggerscript.pex differ diff --git a/scripts/dunkagrenzelanimationresetscript.pex b/scripts/dunkagrenzelanimationresetscript.pex new file mode 100644 index 00000000..276959e6 Binary files /dev/null and b/scripts/dunkagrenzelanimationresetscript.pex differ diff --git a/scripts/dunkarthspirepuzzlemaster.pex b/scripts/dunkarthspirepuzzlemaster.pex new file mode 100644 index 00000000..5925f1b9 Binary files /dev/null and b/scripts/dunkarthspirepuzzlemaster.pex differ diff --git a/scripts/dunkatariahscimitarscript.pex b/scripts/dunkatariahscimitarscript.pex new file mode 100644 index 00000000..71df8e9c Binary files /dev/null and b/scripts/dunkatariahscimitarscript.pex differ diff --git a/scripts/dunmiddentorchscript.pex b/scripts/dunmiddentorchscript.pex new file mode 100644 index 00000000..21049ab9 Binary files /dev/null and b/scripts/dunmiddentorchscript.pex differ diff --git a/scripts/dwepipevalve01script.pex b/scripts/dwepipevalve01script.pex new file mode 100644 index 00000000..848e5111 Binary files /dev/null and b/scripts/dwepipevalve01script.pex differ diff --git a/scripts/dwespherecenturionportscript.pex b/scripts/dwespherecenturionportscript.pex new file mode 100644 index 00000000..f9dd9683 Binary files /dev/null and b/scripts/dwespherecenturionportscript.pex differ diff --git a/scripts/dwespidercenturionpipescript.pex b/scripts/dwespidercenturionpipescript.pex new file mode 100644 index 00000000..3647d0fc Binary files /dev/null and b/scripts/dwespidercenturionpipescript.pex differ diff --git a/scripts/dwesteamcenturionstructurescript.pex b/scripts/dwesteamcenturionstructurescript.pex new file mode 100644 index 00000000..e8184ee6 Binary files /dev/null and b/scripts/dwesteamcenturionstructurescript.pex differ diff --git a/scripts/favordialoguescript.pex b/scripts/favordialoguescript.pex new file mode 100644 index 00000000..099afedf Binary files /dev/null and b/scripts/favordialoguescript.pex differ diff --git a/scripts/flameatronacheffectscript.pex b/scripts/flameatronacheffectscript.pex new file mode 100644 index 00000000..ee911805 Binary files /dev/null and b/scripts/flameatronacheffectscript.pex differ diff --git a/scripts/fxbatscaredscript.pex b/scripts/fxbatscaredscript.pex new file mode 100644 index 00000000..616377b0 Binary files /dev/null and b/scripts/fxbatscaredscript.pex differ diff --git a/scripts/fxbirdfleescript.pex b/scripts/fxbirdfleescript.pex new file mode 100644 index 00000000..f1d61d10 Binary files /dev/null and b/scripts/fxbirdfleescript.pex differ diff --git a/scripts/fxchaurusscript.pex b/scripts/fxchaurusscript.pex new file mode 100644 index 00000000..7afa8f38 Binary files /dev/null and b/scripts/fxchaurusscript.pex differ diff --git a/scripts/fxdragonblooddamagescript.pex b/scripts/fxdragonblooddamagescript.pex new file mode 100644 index 00000000..b283089f Binary files /dev/null and b/scripts/fxdragonblooddamagescript.pex differ diff --git a/scripts/fxdraugrmagicscript.pex b/scripts/fxdraugrmagicscript.pex new file mode 100644 index 00000000..44a03ace Binary files /dev/null and b/scripts/fxdraugrmagicscript.pex differ diff --git a/scripts/fxdustdroponactivatescript.pex b/scripts/fxdustdroponactivatescript.pex new file mode 100644 index 00000000..7a0c7a77 Binary files /dev/null and b/scripts/fxdustdroponactivatescript.pex differ diff --git a/scripts/fxdustdroptrigscript.pex b/scripts/fxdustdroptrigscript.pex new file mode 100644 index 00000000..6de5bfe7 Binary files /dev/null and b/scripts/fxdustdroptrigscript.pex differ diff --git a/scripts/fxdwarvencenturionscript.pex b/scripts/fxdwarvencenturionscript.pex new file mode 100644 index 00000000..7dc559ec Binary files /dev/null and b/scripts/fxdwarvencenturionscript.pex differ diff --git a/scripts/fxdwarvenspherescript.pex b/scripts/fxdwarvenspherescript.pex new file mode 100644 index 00000000..3a7ec313 Binary files /dev/null and b/scripts/fxdwarvenspherescript.pex differ diff --git a/scripts/fxdwarvenspiderscript.pex b/scripts/fxdwarvenspiderscript.pex new file mode 100644 index 00000000..cf1d0473 Binary files /dev/null and b/scripts/fxdwarvenspiderscript.pex differ diff --git a/scripts/fxgreybeardshoutscript.pex b/scripts/fxgreybeardshoutscript.pex new file mode 100644 index 00000000..f2da8c3f Binary files /dev/null and b/scripts/fxgreybeardshoutscript.pex differ diff --git a/scripts/fxmg07dogscript.pex b/scripts/fxmg07dogscript.pex new file mode 100644 index 00000000..6c4f9eb4 Binary files /dev/null and b/scripts/fxmg07dogscript.pex differ diff --git a/scripts/fxsetblendvariablescript.pex b/scripts/fxsetblendvariablescript.pex new file mode 100644 index 00000000..1a1fac67 Binary files /dev/null and b/scripts/fxsetblendvariablescript.pex differ diff --git a/scripts/fxshadowmereemergescript.pex b/scripts/fxshadowmereemergescript.pex new file mode 100644 index 00000000..91ab111e Binary files /dev/null and b/scripts/fxshadowmereemergescript.pex differ diff --git a/scripts/fxskeletonnecroscript.pex b/scripts/fxskeletonnecroscript.pex new file mode 100644 index 00000000..1ca316f8 Binary files /dev/null and b/scripts/fxskeletonnecroscript.pex differ diff --git a/scripts/fxsovengardescript.pex b/scripts/fxsovengardescript.pex new file mode 100644 index 00000000..78b68ae1 Binary files /dev/null and b/scripts/fxsovengardescript.pex differ diff --git a/scripts/fxtriggerambfx.pex b/scripts/fxtriggerambfx.pex new file mode 100644 index 00000000..10902ba9 Binary files /dev/null and b/scripts/fxtriggerambfx.pex differ diff --git a/scripts/hangedmanscript.pex b/scripts/hangedmanscript.pex new file mode 100644 index 00000000..924b5c6d Binary files /dev/null and b/scripts/hangedmanscript.pex differ diff --git a/scripts/hardworkerwoodscript.pex b/scripts/hardworkerwoodscript.pex new file mode 100644 index 00000000..22a51c53 Binary files /dev/null and b/scripts/hardworkerwoodscript.pex differ diff --git a/scripts/hazardbase.pex b/scripts/hazardbase.pex new file mode 100644 index 00000000..e8c7e14f Binary files /dev/null and b/scripts/hazardbase.pex differ diff --git a/scripts/helgenrandomsoundscript.pex b/scripts/helgenrandomsoundscript.pex new file mode 100644 index 00000000..e3920c33 Binary files /dev/null and b/scripts/helgenrandomsoundscript.pex differ diff --git a/scripts/icewraithparticlesscript.pex b/scripts/icewraithparticlesscript.pex new file mode 100644 index 00000000..847ab92a Binary files /dev/null and b/scripts/icewraithparticlesscript.pex differ diff --git a/scripts/itemwithsoudscript.pex b/scripts/itemwithsoudscript.pex new file mode 100644 index 00000000..2900956e Binary files /dev/null and b/scripts/itemwithsoudscript.pex differ diff --git a/scripts/magicabsorbfxscript.pex b/scripts/magicabsorbfxscript.pex new file mode 100644 index 00000000..6c0b464d Binary files /dev/null and b/scripts/magicabsorbfxscript.pex differ diff --git a/scripts/magicattachashpileondeath.pex b/scripts/magicattachashpileondeath.pex new file mode 100644 index 00000000..afa516f2 Binary files /dev/null and b/scripts/magicattachashpileondeath.pex differ diff --git a/scripts/magicbanishscript.pex b/scripts/magicbanishscript.pex new file mode 100644 index 00000000..36169212 Binary files /dev/null and b/scripts/magicbanishscript.pex differ diff --git a/scripts/magicdispelspellonhitscript.pex b/scripts/magicdispelspellonhitscript.pex new file mode 100644 index 00000000..4d68a4bd Binary files /dev/null and b/scripts/magicdispelspellonhitscript.pex differ diff --git a/scripts/magiceffectshaderapply.pex b/scripts/magiceffectshaderapply.pex new file mode 100644 index 00000000..1d509547 Binary files /dev/null and b/scripts/magiceffectshaderapply.pex differ diff --git a/scripts/magiceffectshadersonendscript.pex b/scripts/magiceffectshadersonendscript.pex new file mode 100644 index 00000000..ec960472 Binary files /dev/null and b/scripts/magiceffectshadersonendscript.pex differ diff --git a/scripts/magicimodbasicscript.pex b/scripts/magicimodbasicscript.pex new file mode 100644 index 00000000..1b729cc3 Binary files /dev/null and b/scripts/magicimodbasicscript.pex differ diff --git a/scripts/magicimodbeginloopend.pex b/scripts/magicimodbeginloopend.pex new file mode 100644 index 00000000..86ed719c Binary files /dev/null and b/scripts/magicimodbeginloopend.pex differ diff --git a/scripts/magicimodonplayerhitscript.pex b/scripts/magicimodonplayerhitscript.pex new file mode 100644 index 00000000..86219713 Binary files /dev/null and b/scripts/magicimodonplayerhitscript.pex differ diff --git a/scripts/magicnighteyescript.pex b/scripts/magicnighteyescript.pex new file mode 100644 index 00000000..8a1542c8 Binary files /dev/null and b/scripts/magicnighteyescript.pex differ diff --git a/scripts/magicplaceactivatorscript.pex b/scripts/magicplaceactivatorscript.pex new file mode 100644 index 00000000..2adb2f9a Binary files /dev/null and b/scripts/magicplaceactivatorscript.pex differ diff --git a/scripts/magicplayeffectshaderonhitscript.pex b/scripts/magicplayeffectshaderonhitscript.pex new file mode 100644 index 00000000..8a45b73c Binary files /dev/null and b/scripts/magicplayeffectshaderonhitscript.pex differ diff --git a/scripts/magicsetactoralphascript.pex b/scripts/magicsetactoralphascript.pex new file mode 100644 index 00000000..629ae8cd Binary files /dev/null and b/scripts/magicsetactoralphascript.pex differ diff --git a/scripts/mg08paralysiseffectscript.pex b/scripts/mg08paralysiseffectscript.pex new file mode 100644 index 00000000..d060f480 Binary files /dev/null and b/scripts/mg08paralysiseffectscript.pex differ diff --git a/scripts/movingtrap.pex b/scripts/movingtrap.pex new file mode 100644 index 00000000..b44a2758 Binary files /dev/null and b/scripts/movingtrap.pex differ diff --git a/scripts/mqgreybeardabsorbscript.pex b/scripts/mqgreybeardabsorbscript.pex new file mode 100644 index 00000000..6d6f94a9 Binary files /dev/null and b/scripts/mqgreybeardabsorbscript.pex differ diff --git a/scripts/mqkilldragonscript.pex b/scripts/mqkilldragonscript.pex new file mode 100644 index 00000000..242ea8d1 Binary files /dev/null and b/scripts/mqkilldragonscript.pex differ diff --git a/scripts/ms10questscript.pex b/scripts/ms10questscript.pex new file mode 100644 index 00000000..b3a4b7d5 Binary files /dev/null and b/scripts/ms10questscript.pex differ diff --git a/scripts/ms11questscript.pex b/scripts/ms11questscript.pex new file mode 100644 index 00000000..63cf6c73 Binary files /dev/null and b/scripts/ms11questscript.pex differ diff --git a/scripts/nightingalesecdoorscript.pex b/scripts/nightingalesecdoorscript.pex new file mode 100644 index 00000000..20bcc010 Binary files /dev/null and b/scripts/nightingalesecdoorscript.pex differ diff --git a/scripts/noflightabilityscript.pex b/scripts/noflightabilityscript.pex new file mode 100644 index 00000000..eb36e6c2 Binary files /dev/null and b/scripts/noflightabilityscript.pex differ diff --git a/scripts/norlever01script.pex b/scripts/norlever01script.pex new file mode 100644 index 00000000..55191260 Binary files /dev/null and b/scripts/norlever01script.pex differ diff --git a/scripts/norportcullisscript.pex b/scripts/norportcullisscript.pex new file mode 100644 index 00000000..fb054707 Binary files /dev/null and b/scripts/norportcullisscript.pex differ diff --git a/scripts/norpullbar01script.pex b/scripts/norpullbar01script.pex new file mode 100644 index 00000000..6724adf3 Binary files /dev/null and b/scripts/norpullbar01script.pex differ diff --git a/scripts/norrotatingdoorscript.pex b/scripts/norrotatingdoorscript.pex new file mode 100644 index 00000000..f2ee98ee Binary files /dev/null and b/scripts/norrotatingdoorscript.pex differ diff --git a/scripts/norsarcophagustopanim01script.pex b/scripts/norsarcophagustopanim01script.pex new file mode 100644 index 00000000..3cde93e0 Binary files /dev/null and b/scripts/norsarcophagustopanim01script.pex differ diff --git a/scripts/pdbentrancequestscript.pex b/scripts/pdbentrancequestscript.pex new file mode 100644 index 00000000..2c6a4837 Binary files /dev/null and b/scripts/pdbentrancequestscript.pex differ diff --git a/scripts/pf_ambushsleeplinkedref_00048abc.pex b/scripts/pf_ambushsleeplinkedref_00048abc.pex new file mode 100644 index 00000000..0f052c27 Binary files /dev/null and b/scripts/pf_ambushsleeplinkedref_00048abc.pex differ diff --git a/scripts/pf_carryfirewood_000d97fa.pex b/scripts/pf_carryfirewood_000d97fa.pex new file mode 100644 index 00000000..c10091f8 Binary files /dev/null and b/scripts/pf_carryfirewood_000d97fa.pex differ diff --git a/scripts/pf_dgintimidatespectatorpacka_000aa053.pex b/scripts/pf_dgintimidatespectatorpacka_000aa053.pex new file mode 100644 index 00000000..343d416b Binary files /dev/null and b/scripts/pf_dgintimidatespectatorpacka_000aa053.pex differ diff --git a/scripts/pf_dgintimidatespectatorpacka_000aa054.pex b/scripts/pf_dgintimidatespectatorpacka_000aa054.pex new file mode 100644 index 00000000..4671faa2 Binary files /dev/null and b/scripts/pf_dgintimidatespectatorpacka_000aa054.pex differ diff --git a/scripts/physicstraphit.pex b/scripts/physicstraphit.pex new file mode 100644 index 00000000..2bf858c3 Binary files /dev/null and b/scripts/physicstraphit.pex differ diff --git a/scripts/playerbookshelfclicktriggerscript.pex b/scripts/playerbookshelfclicktriggerscript.pex new file mode 100644 index 00000000..1e64bac3 Binary files /dev/null and b/scripts/playerbookshelfclicktriggerscript.pex differ diff --git a/scripts/playerbookshelfcontainerscript.pex b/scripts/playerbookshelfcontainerscript.pex new file mode 100644 index 00000000..6cf52a62 Binary files /dev/null and b/scripts/playerbookshelfcontainerscript.pex differ diff --git a/scripts/playerbookshelftriggerscript.pex b/scripts/playerbookshelftriggerscript.pex new file mode 100644 index 00000000..596a4f97 Binary files /dev/null and b/scripts/playerbookshelftriggerscript.pex differ diff --git a/scripts/playerpotionrackclicktriggerscript.pex b/scripts/playerpotionrackclicktriggerscript.pex new file mode 100644 index 00000000..add70cbd Binary files /dev/null and b/scripts/playerpotionrackclicktriggerscript.pex differ diff --git a/scripts/playerpotionracktriggerscript.pex b/scripts/playerpotionracktriggerscript.pex new file mode 100644 index 00000000..58c1a5aa Binary files /dev/null and b/scripts/playerpotionracktriggerscript.pex differ diff --git a/scripts/playerwerewolfchangescript.pex b/scripts/playerwerewolfchangescript.pex new file mode 100644 index 00000000..2229f406 Binary files /dev/null and b/scripts/playerwerewolfchangescript.pex differ diff --git a/scripts/pressureplate.pex b/scripts/pressureplate.pex new file mode 100644 index 00000000..73835927 Binary files /dev/null and b/scripts/pressureplate.pex differ diff --git a/scripts/pressurereleaseplate.pex b/scripts/pressurereleaseplate.pex new file mode 100644 index 00000000..5a72d05d Binary files /dev/null and b/scripts/pressurereleaseplate.pex differ diff --git a/scripts/reanimateashpile.pex b/scripts/reanimateashpile.pex new file mode 100644 index 00000000..2b4355cb Binary files /dev/null and b/scripts/reanimateashpile.pex differ diff --git a/scripts/resourcefurniturescript.pex b/scripts/resourcefurniturescript.pex new file mode 100644 index 00000000..2e57ec91 Binary files /dev/null and b/scripts/resourcefurniturescript.pex differ diff --git a/scripts/resourceobjectsawmillscript.pex b/scripts/resourceobjectsawmillscript.pex new file mode 100644 index 00000000..5e46c5f9 Binary files /dev/null and b/scripts/resourceobjectsawmillscript.pex differ diff --git a/scripts/resourceobjectscript.pex b/scripts/resourceobjectscript.pex new file mode 100644 index 00000000..e7107c29 Binary files /dev/null and b/scripts/resourceobjectscript.pex differ diff --git a/scripts/sayonhitbymagiceffectscript.pex b/scripts/sayonhitbymagiceffectscript.pex new file mode 100644 index 00000000..e35bfa01 Binary files /dev/null and b/scripts/sayonhitbymagiceffectscript.pex differ diff --git a/scripts/sethirelingrehire.pex b/scripts/sethirelingrehire.pex new file mode 100644 index 00000000..401fd9c0 Binary files /dev/null and b/scripts/sethirelingrehire.pex differ diff --git a/scripts/shaderparticlegeometryscript.pex b/scripts/shaderparticlegeometryscript.pex new file mode 100644 index 00000000..5ca8b964 Binary files /dev/null and b/scripts/shaderparticlegeometryscript.pex differ diff --git a/scripts/silverswordscript.pex b/scripts/silverswordscript.pex new file mode 100644 index 00000000..b07995c0 Binary files /dev/null and b/scripts/silverswordscript.pex differ diff --git a/scripts/skyhavensconcescript.pex b/scripts/skyhavensconcescript.pex new file mode 100644 index 00000000..4a67a579 Binary files /dev/null and b/scripts/skyhavensconcescript.pex differ diff --git a/scripts/speartrap.pex b/scripts/speartrap.pex new file mode 100644 index 00000000..351ad5ef Binary files /dev/null and b/scripts/speartrap.pex differ diff --git a/scripts/spiderwebanimationsscript.pex b/scripts/spiderwebanimationsscript.pex new file mode 100644 index 00000000..d1f5950b Binary files /dev/null and b/scripts/spiderwebanimationsscript.pex differ diff --git a/scripts/spriggancallanimalsaoe.pex b/scripts/spriggancallanimalsaoe.pex new file mode 100644 index 00000000..8aac95ff Binary files /dev/null and b/scripts/spriggancallanimalsaoe.pex differ diff --git a/scripts/sprigganswarmactorscript.pex b/scripts/sprigganswarmactorscript.pex new file mode 100644 index 00000000..bf4f581f Binary files /dev/null and b/scripts/sprigganswarmactorscript.pex differ diff --git a/scripts/summontargetfxactivatorscript.pex b/scripts/summontargetfxactivatorscript.pex new file mode 100644 index 00000000..318044a6 Binary files /dev/null and b/scripts/summontargetfxactivatorscript.pex differ diff --git a/scripts/trapbase.pex b/scripts/trapbase.pex new file mode 100644 index 00000000..4d81b57f Binary files /dev/null and b/scripts/trapbase.pex differ diff --git a/scripts/trapbear.pex b/scripts/trapbear.pex new file mode 100644 index 00000000..02262893 Binary files /dev/null and b/scripts/trapbear.pex differ diff --git a/scripts/trapdweballista.pex b/scripts/trapdweballista.pex new file mode 100644 index 00000000..d30aad5e Binary files /dev/null and b/scripts/trapdweballista.pex differ diff --git a/scripts/trapdweflamepillar.pex b/scripts/trapdweflamepillar.pex new file mode 100644 index 00000000..077fd373 Binary files /dev/null and b/scripts/trapdweflamepillar.pex differ diff --git a/scripts/trapdweflamepillarhit.pex b/scripts/trapdweflamepillarhit.pex new file mode 100644 index 00000000..957fe846 Binary files /dev/null and b/scripts/trapdweflamepillarhit.pex differ diff --git a/scripts/trapdwepiston.pex b/scripts/trapdwepiston.pex new file mode 100644 index 00000000..03e3b74e Binary files /dev/null and b/scripts/trapdwepiston.pex differ diff --git a/scripts/trapfireplate.pex b/scripts/trapfireplate.pex new file mode 100644 index 00000000..c43623a4 Binary files /dev/null and b/scripts/trapfireplate.pex differ diff --git a/scripts/trapgenericeffecthazard.pex b/scripts/trapgenericeffecthazard.pex new file mode 100644 index 00000000..dc6e5c43 Binary files /dev/null and b/scripts/trapgenericeffecthazard.pex differ diff --git a/scripts/traphitbase.pex b/scripts/traphitbase.pex new file mode 100644 index 00000000..676f6743 Binary files /dev/null and b/scripts/traphitbase.pex differ diff --git a/scripts/traplever.pex b/scripts/traplever.pex new file mode 100644 index 00000000..8d4a5c4c Binary files /dev/null and b/scripts/traplever.pex differ diff --git a/scripts/trapnorplatform.pex b/scripts/trapnorplatform.pex new file mode 100644 index 00000000..a77e3830 Binary files /dev/null and b/scripts/trapnorplatform.pex differ diff --git a/scripts/trapoilpool.pex b/scripts/trapoilpool.pex new file mode 100644 index 00000000..29270704 Binary files /dev/null and b/scripts/trapoilpool.pex differ diff --git a/scripts/trappoisongas.pex b/scripts/trappoisongas.pex new file mode 100644 index 00000000..7dd82bca Binary files /dev/null and b/scripts/trappoisongas.pex differ diff --git a/scripts/trappoisongascough.pex b/scripts/trappoisongascough.pex new file mode 100644 index 00000000..6c7de511 Binary files /dev/null and b/scripts/trappoisongascough.pex differ diff --git a/scripts/trapriggedrockfall.pex b/scripts/trapriggedrockfall.pex new file mode 100644 index 00000000..4233d29e Binary files /dev/null and b/scripts/trapriggedrockfall.pex differ diff --git a/scripts/traprockfalleffects.pex b/scripts/traprockfalleffects.pex new file mode 100644 index 00000000..ec68aabb Binary files /dev/null and b/scripts/traprockfalleffects.pex differ diff --git a/scripts/trapsoulgemcontroller.pex b/scripts/trapsoulgemcontroller.pex new file mode 100644 index 00000000..9e45ec77 Binary files /dev/null and b/scripts/trapsoulgemcontroller.pex differ diff --git a/scripts/traptriggerbase.pex b/scripts/traptriggerbase.pex new file mode 100644 index 00000000..ef07f151 Binary files /dev/null and b/scripts/traptriggerbase.pex differ diff --git a/scripts/traptriggerhinge.pex b/scripts/traptriggerhinge.pex new file mode 100644 index 00000000..eb439c42 Binary files /dev/null and b/scripts/traptriggerhinge.pex differ diff --git a/scripts/traptriggertimeinterval.pex b/scripts/traptriggertimeinterval.pex new file mode 100644 index 00000000..572b8e75 Binary files /dev/null and b/scripts/traptriggertimeinterval.pex differ diff --git a/scripts/tripwire.pex b/scripts/tripwire.pex new file mode 100644 index 00000000..389460ac Binary files /dev/null and b/scripts/tripwire.pex differ diff --git a/scripts/voiceiceformscript.pex b/scripts/voiceiceformscript.pex new file mode 100644 index 00000000..9a6afa13 Binary files /dev/null and b/scripts/voiceiceformscript.pex differ diff --git a/scripts/voiceobjectscript.pex b/scripts/voiceobjectscript.pex new file mode 100644 index 00000000..f71784c9 Binary files /dev/null and b/scripts/voiceobjectscript.pex differ diff --git a/scripts/voicepusheffectscript.pex b/scripts/voicepusheffectscript.pex new file mode 100644 index 00000000..e0b8f2cb Binary files /dev/null and b/scripts/voicepusheffectscript.pex differ diff --git a/scripts/weaponracktriggerscript.pex b/scripts/weaponracktriggerscript.pex new file mode 100644 index 00000000..17f070d0 Binary files /dev/null and b/scripts/weaponracktriggerscript.pex differ diff --git a/scripts/webdestructiblescript.pex b/scripts/webdestructiblescript.pex new file mode 100644 index 00000000..00e284d6 Binary files /dev/null and b/scripts/webdestructiblescript.pex differ diff --git a/scripts/werewolfchangeeffectscript.pex b/scripts/werewolfchangeeffectscript.pex new file mode 100644 index 00000000..3fbfdcbe Binary files /dev/null and b/scripts/werewolfchangeeffectscript.pex differ diff --git a/scripts/werewolftransformvisual.pex b/scripts/werewolftransformvisual.pex new file mode 100644 index 00000000..18cda70a Binary files /dev/null and b/scripts/werewolftransformvisual.pex differ diff --git a/scripts/wifunctionsscript.pex b/scripts/wifunctionsscript.pex new file mode 100644 index 00000000..e9d0795c Binary files /dev/null and b/scripts/wifunctionsscript.pex differ diff --git a/source/scripts/abforswornbriarheartscript.psc b/source/scripts/abforswornbriarheartscript.psc new file mode 100644 index 00000000..85b60966 --- /dev/null +++ b/source/scripts/abforswornbriarheartscript.psc @@ -0,0 +1,31 @@ +Scriptname abForswornBriarheartScript extends ActiveMagicEffect + +ingredient property BriarHeart auto +{The briarheart object.} +armor property ArmorBriarHeart auto +armor property ArmorBriarHeartEmpty auto + +actor property mySelf auto hidden + + EVENT OnEffectStart(Actor Target, Actor Caster) + mySelf = caster + Caster.AddInventoryEventFilter(briarHeart) + endEVENT + + EVENT OnItemRemoved(Form objectTaken, int aiItemCount, ObjectReference refTaken, ObjectReference akDestContainer) + if objectTaken == briarHeart +; debug.trace("Briarheart warrior "+mySelf+" has had his heart removed!") + + ; kill the warrior, blame it on whoever took the heart + if myself.isDead() == FALSE + mySelf.kill(akDestContainer as actor) + endif + + ; dead or alive, switch to "empty" cavity when the briarheart is taken + myself.addItem(ArmorBriarHeartEmpty,1) + utility.wait(0.25) + mySelf.removeItem(armorBriarHeart,(mySelf.getItemCount(armorBriarHeart))) + myself.equipItem(ArmorBriarHeartEmpty,TRUE,TRUE) + endif + endEVENT + \ No newline at end of file diff --git a/source/scripts/achievementsscript.psc b/source/scripts/achievementsscript.psc new file mode 100644 index 00000000..bbf1d19d --- /dev/null +++ b/source/scripts/achievementsscript.psc @@ -0,0 +1,214 @@ +Scriptname AchievementsScript extends Quest + +; Define a property that points to the script on this quest, and call the function +; +; Declare this in your script: +; AchievementsScript Property AchievementsQuest Auto +; +; Call this function: +; AchievementsQuest.IncSideQuests() + +Int SideQuestCount +Int MaxSideQuests = 10 +Int DaedricArtifactCount +Int MaxDaedricArtifacts = 15 + +; Required values that stats incremented in code need to meet in order to obtain the associated achievement +Int NumCompletedMiscObjectivesNeeded = 50 +Int NumLocksPickedNeeded = 50 +Int NumPocketsPickedNeeded = 50 +Int BountyNeeded = 1000 +Int GoldNeeded = 100000 +Int NumClearedDungeonsNeeded = 50 +Int SkillValueNeeded = 100 +Int NumLocationDiscoveriesNeeded = 100 +Int NumSolstheimLocationDiscoveriesNeeded = 30 +Int NumReadSkillBooksNeeded = 50 +Int NumDragonSoulsAbsorbed = 20 +Int NumShoutsLearnedNeeded = 20 +Int ApprenticeLevel = 5 +Int AdeptLevel = 10 +Int ExpertLevel = 25 +Int MasterLevel = 50 + +; _____________ +;| | +;| EVENTS | +;|_____________| +EVENT OnInit() + ; Listen for when tracked stats are incremented + RegisterForTrackedStatsEvent() +endEVENT + +EVENT OnTrackedStatsEvent(string statFilter, int statValue) + ; Hero of the People achievement + if (statFilter == "Misc Objectives Completed") + if (statValue >= NumCompletedMiscObjectivesNeeded) + Game.AddAchievement(25) + endif + ; Thief achievement + elseIf (statFilter == "Locks Picked") + if (statValue >= NumLocksPickedNeeded) + if (Game.QueryStat("Pockets Picked") >= NumPocketsPickedNeeded) + Game.AddAchievement(27) + endif + endif + elseIf (statFilter == "Pockets Picked") + if (statValue >= NumPocketsPickedNeeded) + if (Game.QueryStat("Locks Picked") >= NumLocksPickedNeeded) + Game.AddAchievement(27) + endif + endif + ; Artificer achievement + elseIf (statFilter == "Weapons Made" || statFilter == "Armor Made") + if (Game.QueryStat("Magic Items Made") && (Game.QueryStat("Potions Mixed") || Game.QueryStat("Poisons Mixed"))) + Game.AddAchievement(34) + endif + elseIf (statFilter == "Magic Items Made") + if ((Game.QueryStat("Weapons Made") || Game.QueryStat("Armor Made")) && (Game.QueryStat("Potions Mixed") || Game.QueryStat("Poisons Mixed"))) + Game.AddAchievement(34) + endif + elseIf (statFilter == "Potions Mixed" || statFilter == "Poisons Mixed") + if ((Game.QueryStat("Weapons Made") || Game.QueryStat("Armor Made")) && Game.QueryStat("Magic Items Made")) + Game.AddAchievement(34) + endif + ; Stalhrim Crafter achievement + elseIf (statFilter == "StalhrimItemsCrafted") + Game.AddAchievement(72) + ; Master Criminal achievement + elseIf (statFilter == "Eastmarch Bounty" || statFilter == "Falkreath Bounty" || statFilter == "Haafingar Bounty" || statFilter == "Hjaalmarch Bounty" || statFilter == "The Pale Bounty" || statFilter == "The Reach Bounty" ||statFilter == "The Rift Bounty" || statFilter == "Whiterun Bounty" || statFilter == "Winterhold Bounty" ) + if (statValue >= BountyNeeded) + if (Game.QueryStat("Eastmarch Bounty") >= BountyNeeded && Game.QueryStat("Falkreath Bounty") >= BountyNeeded && Game.QueryStat("Haafingar Bounty") >= BountyNeeded && Game.QueryStat("Hjaalmarch Bounty") >= BountyNeeded && Game.QueryStat("The Pale Bounty") >= BountyNeeded && Game.QueryStat("The Reach Bounty") >= BountyNeeded && Game.QueryStat("The Rift Bounty") >= BountyNeeded && Game.QueryStat("Whiterun Bounty") >= BountyNeeded && Game.QueryStat("Winterhold Bounty") >= BountyNeeded) + Game.AddAchievement(35) + endif + endif + ; Golden Touch achievement + elseIf (statFilter == "Most Gold Carried") + if (statValue >= GoldNeeded) + Game.AddAchievement(36) + endif + ; Delver achievement + elseIf (statFilter == "Dungeons Cleared") + if (statValue >= NumClearedDungeonsNeeded) + Game.AddAchievement(37) + endif + ; Skill Master achievement + elseIf (statFilter == "Skill Increases") + if (statValue >= SkillValueNeeded) + Game.AddAchievement(38) + endif + ; Explorer achievement + elseIf (statFilter == "Locations Discovered") + if (statValue >= NumLocationDiscoveriesNeeded) + Game.AddAchievement(39) + endif + ; Solstheim Explorer achievement + elseIf (statFilter == "Solstheim Locations Discovered") + if (statValue >= NumSolstheimLocationDiscoveriesNeeded) + Game.AddAchievement(75) + endif + ; Reader achievement + elseIf (statFilter == "Skill Books Read") + if (statValue >= NumReadSkillBooksNeeded) + Game.AddAchievement(40) + endif + elseIf (statFilter == "Dragon Souls Collected") + ; Dragon Soul achievement + Game.AddAchievement(43) + ; Dragon Hunter achievement + if (statValue >= NumDragonSoulsAbsorbed) + Game.AddAchievement(44) + endif + ; Words of Power achievement + elseIf (statFilter == "Shouts Mastered") + Game.AddAchievement (45) + ; Thu'um Master achievement + elseIf (statFilter == "Shouts Learned") + if (statValue >= NumShoutsLearnedNeeded) + Game.AddAchievement(46) + endif + elseIf (statFilter == "Level Increases") + ; Apprentice achievement + if (statValue >= ApprenticeLevel) + Game.AddAchievement(47) + endif + ; Adept achievement + if (statValue >= AdeptLevel) + Game.AddAchievement(48) + endif + ; Expert achievement + if (statValue >= ExpertLevel) + Game.AddAchievement(49) + endif + ; Master achievement + if (statValue >= MasterLevel) + Game.AddAchievement(50) + endif + endif +endEVENT + +; _____________ +;| | +;| FUNCTIONS | +;|_____________| +Function IncSideQuests() + SideQuestCount += 1 + Game.IncrementStat( "Side Quests Completed" ) + If SideQuestCount >= MaxSideQuests + Game.AddAchievement(24) + EndIf +EndFunction + +Function IncDaedricArtifacts() + DaedricArtifactCount += 1 + Game.AddAchievement(41) + If DaedricArtifactCount >= MaxDaedricArtifacts + Game.AddAchievement(42) + EndIf +EndFunction + +Function IncDaedricQuests() + ; WJS - empty call, UI handles this stat, but in case we need a function call later for when Daedric Quests complete + ;Game.IncrementStat( "Daedric Quests Completed" ) +EndFunction + +Function IncHardWorker(int AkObjectType) + + + if HardWorkerDone==false + if AkObjectType==1 + HardWorkerChoppedWood=true + if HardWorkerMinedOre == true + if HardWorkerCookedFood == true + Game.AddAchievement(26) + HardWorkerDone=true + endif + endif + elseif AkObjectType==2 + HardWorkerMinedOre=true + if HardWorkerChoppedWood == true + if HardWorkerCookedFood == true + Game.AddAchievement(26) + HardWorkerDone=true + endif + endif + elseif AkObjectType==3 + HardWorkerCookedFood=true + if HardWorkerChoppedWood == true + if HardWorkerMinedOre == true + Game.AddAchievement(26) + HardWorkerDone=true + endif + endif + endif + endif +EndFunction + + +Bool Property HardWorkerChoppedWood Auto + +Bool Property HardWorkerMinedOre Auto + +Bool Property HardWorkerCookedFood Auto + +Bool Property HardWorkerDone Auto \ No newline at end of file diff --git a/source/scripts/activateselfoncombatbegin.psc b/source/scripts/activateselfoncombatbegin.psc new file mode 100644 index 00000000..33437830 --- /dev/null +++ b/source/scripts/activateselfoncombatbegin.psc @@ -0,0 +1,19 @@ +ScriptName activateSelfOnCombatBegin extends Actor +{Script that lives on an actor that simply activates itself on Combat Begin} + +import game +import debug + +auto State waiting + Event OnCombatStateChanged(Actor actorRef, int combatState) + if combatState != 0 ; 0 = not in combat, so if the state isn't 0, they entered combat + gotoState("allDone") + activate(Self) + endIf + endEvent +endState + +State allDone + ;do nothing +endState + \ No newline at end of file diff --git a/source/scripts/atronachfrostscript.psc b/source/scripts/atronachfrostscript.psc new file mode 100644 index 00000000..43765dd6 --- /dev/null +++ b/source/scripts/atronachfrostscript.psc @@ -0,0 +1,32 @@ +Scriptname AtronachFrostScript extends ActiveMagicEffect +;=============================================== + +;=============================================== +;VisualEffect Property AtronachFrostEffect01 Auto +EffectShader Property AtronachFrostFXS Auto +EffectShader Property AtronachUnsummonDeathFXS Auto +Explosion Property deathExplosion Auto +Actor selfRef +int atronachHealth + + EVENT OnEffectStart(Actor Target, Actor Caster) + selfRef = caster + AtronachFrostFXS.Play(selfRef) + ENDEVENT + + Event OnEffectFinish(Actor akTarget, Actor akCaster) + AtronachFrostFXS.Stop(selfRef) + ENDEVENT + + EVENT onDying(actor myKiller) + atronachHealth = selfRef.GetAV("Health") as int + if atronachHealth > 0 +; debug.trace("frost health > 0") + AtronachFrostFXS.Stop(selfRef) + AtronachUnsummonDeathFXS.Play(selfRef) + elseIf atronachHealth <= 0 +; debug.trace("frost health <= 0") + selfRef.placeAtMe(deathExplosion) + AtronachFrostFXS.Stop(selfRef) + endIf + ENDEVENT diff --git a/source/scripts/barreddoor.psc b/source/scripts/barreddoor.psc new file mode 100644 index 00000000..9b312d7c --- /dev/null +++ b/source/scripts/barreddoor.psc @@ -0,0 +1,55 @@ +scriptname barredDoor extends objectReference +{script which must be on any barred door} +;======================================================================================; +; PROPERTIES / +;=============/ +bool property barred = true auto hidden +{is this door barred? Controlled by linked DoorBar object. Default:true} +bool property busy = false auto hidden +{bool that tracks whether the BOLT is moving} +message property BarredMSG auto +{set the "door is barred from the other side" message here"} +message property UnlockMeMSG auto +{set the "must raise deadbolt" message here"} +sound property barredSFX auto +{set the "ker-clunk" sfx for a door that cannot open here} + +; need to communicate with my bar's script +doorBar barScript +objectReference myLink + +EVENT onCellLoad() + myLink = getLinkedRef() + barScript = myLink as doorBar +endEVENT + +EVENT onActivate(objectReference actronaut) +; ;debug.trace("bolt state is: " + barScript.getState() + "(" + barScript + ")") + if busy == TRUE + ; do nothing if the bolt is in motion + else + if barred == true && actronaut == game.getPlayer() + if actronaut.getDistance(self) < actronaut.getDistance(myLink) + ; I cannot be opened from this side! + barredMSG.show() + else + ; player is closer to bar than the door, so must be on the "right" side + UnlockMeMSG.show() + endif + ; either way, play a nice ker-chunk sound to feedback why door isn't opening + barredSFX.play(self) + ; add a tiny rumble bump for good measure + game.shakeController(0.1, 0.1, 0.1) + else + ; do a redundant check here + if getOpenState() == 3 || busy == TRUE +; ;debug.trace("Something is wrong, do nothing" + self) + return + else +; ;debug.trace("open " + self) + ; not barred, so allow normal activation. + endif + endif + endif +endEVENT + \ No newline at end of file diff --git a/source/scripts/batteringtrap.psc b/source/scripts/batteringtrap.psc new file mode 100644 index 00000000..4f663bfc --- /dev/null +++ b/source/scripts/batteringtrap.psc @@ -0,0 +1,82 @@ +scriptName BatteringTrap extends MovingTrap +; +; +;This is the script for the blade trap +;Activating the trap causes it to toggle on and off +;If activated while in the process of stopping, it should be able to handle that. +;================================================================ + +import debug +import utility + +;If Loop is true, it swings until activated again. +;If Loop is false, it swings once when activated. +bool restartLooping = false +bool finishedPlaying = false +float property initialDelay = 0.25 auto +bool property resetEventRecieved = False auto hidden + + +;----------------------------------- + +Function fireTrap() + + ;Basic wind up and fire once checking +; ;debug.TRACE("fireTrap called") + WindupSound.play( self as ObjectReference) ;play windup sound + ResolveLeveledDamage() + wait( initialDelay ) ;wait for windup +; ;debug.TRACE("Initial Delay complete") + registerForAnimationEvent(self, "reset") + if (fireOnlyOnce == True) ;If this can be fired only once then disarm + trapDisarmed = True + endif + +; ;debug.TRACE("Looping =") +; ;debug.TRACE(Loop) + + ;Trap Guts + while(finishedPlaying == False) && isloaded + ;TRACE("playing anim Trigger") + hitBase.goToState("CanHit") + PlayAnimationAndWait("Trigger", "BackSwing") + hitBase.goToState("CannotHit") + + while !resetEventRecieved && isLoaded +; ;debug.Trace(self + " is waiting for animationEvent") + utility.wait(0.5) + endWhile + finishedPlaying = True + resetEventRecieved = False + if (loop == TRUE) ;Reset Limiter + resetLimiter() + endif +; debug.Trace(self + " finished main while loop") + endWhile + + unregisterForAnimationEvent(self, "reset") + goToState("Reset") +; ;debug.TRACE("fireTrap has finished") + PlayAnimationAndWait( "reset", "off" ) + +endFunction + +Function ResetLimiter() + finishedPlaying = False + ;TrapHitBase hitBase = (self as objectReference) as TrapHitBase + ;hitBase.goToState("CanHit") +EndFunction + +Event onLoad() + hitBase = (self as objectReference) as TrapHitBase +endEvent + + +Event OnAnimationEvent(ObjectReference akSource, string asEventName) +; ;debug.Trace(self + " has recieved animation event = " + asEventName) + if akSource == (self as objectReference) && asEventName == "reset" + resetEventRecieved = TRUE + endif + +endEvent + diff --git a/source/scripts/beehivehavokonhit.psc b/source/scripts/beehivehavokonhit.psc new file mode 100644 index 00000000..149abf74 --- /dev/null +++ b/source/scripts/beehivehavokonhit.psc @@ -0,0 +1,13 @@ +Scriptname BeeHiveHavokOnHit extends ObjectReference +{Stops the beehive from havoking until hit.} + + +Event OnLoad() +; Debug.Trace("This object is loaded, playing animations should work now") + self.SetMotionType(Motion_Keyframed, true) +endEvent + +Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) +; Debug.Trace("I just got hit by something") + self.SetMotionType(Motion_Dynamic, true) +endEvent diff --git a/source/scripts/blackreachdoorscript.psc b/source/scripts/blackreachdoorscript.psc new file mode 100644 index 00000000..bab8e1fa --- /dev/null +++ b/source/scripts/blackreachdoorscript.psc @@ -0,0 +1,65 @@ +Scriptname BlackreachDoorScript extends ObjectReference Conditional +{Script to open the door to blackreach when activated by the lock.} + +import game +import debug +import utility + +bool property isOpen = false auto Conditional +{set to true to start open} + +bool property isAnimating = false auto Hidden +{is the activator currently animating from one state to another?} + +string property openAnim = "Down" auto Hidden +{animation to play when opening} + +string property openEvent = "TransDown" auto Hidden +{open event name - waits for this event before considering itself "open"} + +int myState = 1 +; true when static or animating +; 0 == open or opening +; 1 == closed or closing + +EVENT OnLoad() + if (isOpen ) + myState = 0 + endif +endEVENT + +auto STATE waiting ; waiting to be activated + EVENT onActivate (objectReference triggerRef) + ; switch open state when activated + SetOpen(!isOpen) + endEVENT +endState + +STATE busy + ; This is the state when I'm busy animating + EVENT onActivate (objectReference triggerRef) + trace (self + " Busy") + endEVENT +endSTATE + +function SetOpen(bool abOpen = true) + ; if busy, wait to finish + while getState() == "busy" + wait(1) + endWhile + ; open + isAnimating = true + if !isOpen + gotoState ("busy") + trace(self + " Opening") + playAnimationandWait(openAnim, openEvent) ; Animate Open + endif + trace(self + " Opened") + isOpen = true + gotoState("done") + isAnimating = false +endFunction + +STATE done + ; This is the end state, player should not be able to reactivate +endSTATE \ No newline at end of file diff --git a/source/scripts/blacksmithforge01.psc b/source/scripts/blacksmithforge01.psc new file mode 100644 index 00000000..2a1e8ee0 --- /dev/null +++ b/source/scripts/blacksmithforge01.psc @@ -0,0 +1,14 @@ +scriptName BlacksmithForge01 extends ObjectReference +import Debug + +spell property FlameDamage Auto + +EVENT onActivate ( objectReference triggerRef ) + playAnimation("activate") +endEvent + +Event OnTriggerEnter ( objectReference triggerRef ) + if (triggerRef == Game.GetPlayer()) + FlameDamage.Cast(triggerRef, triggerRef) + endIf +endEvent diff --git a/source/scripts/bladetrap.psc b/source/scripts/bladetrap.psc new file mode 100644 index 00000000..acebe36e --- /dev/null +++ b/source/scripts/bladetrap.psc @@ -0,0 +1,65 @@ +scriptName BladeTrap extends MovingTrap +; +; +;This is the script for the blade trap +;Activating the trap causes it to toggle on and off +;If activated while in the process of stopping, it should be able to handle that. +;================================================================ + + + +import debug +import utility + +;If Loop is true, it swings until activated again. +;If Loop is false, it swings once when activated. +bool restartLooping = false +bool finishedPlaying = false +float property initialDelay = 0.25 auto + + +;----------------------------------- + +Function fireTrap() + ;PlayAnimationAndWait( "reset", "off" ) + ;Basic wind up and fire once checking + ;TRACE("fireTrap called") + ResolveLeveledDamage() + hitBase.goToState("CanHit") + isFiring = True + WindupSound.play( self as ObjectReference) ;play windup sound + wait( initialDelay ) ;wait for windup + ;TRACE("Initial Delay complete") + + if (fireOnlyOnce == True) ;If this can be fired only once then disarm + trapDisarmed = True + endif + + ;TRACE("Looping =") + ;TRACE(Loop) + + ;Trap Guts + while(finishedPlaying == False && isLoaded == TRUE) + ;TRACE("playing anim Single") + + PlayAnimationAndWait("Single", "reset") + finishedPlaying = True + + if (loop == TRUE) ;Reset Limiter + resetLimiter() + endif + wait(0.0) + endWhile + + if isLoaded + isFiring = false + hitBase.goToState("CannotHit") + ;PlayAnimationAndWait( "reset", "off" ) + goToState("Reset") + endif + +endFunction + +Function ResetLimiter() + finishedPlaying = False +EndFunction diff --git a/source/scripts/boundboweffectscript.psc b/source/scripts/boundboweffectscript.psc new file mode 100644 index 00000000..e89f34f9 --- /dev/null +++ b/source/scripts/boundboweffectscript.psc @@ -0,0 +1,26 @@ +Scriptname BoundBowEffectScript extends ActiveMagicEffect +; Modder's Note - this feature was removed for functionality reasons. However; I'm leaving the script in for anybody who may want to play with bound arrows. -JB + + +Ammo Property boundArrow Auto +MagicEffect Property BoundBowFFSelf Auto + +EVENT OnEffectStart(Actor Target, Actor Caster) +; debug.trace("Bound Bow - Effect Starting - add and equip bound arrows") + caster.additem(boundArrow,100,TRUE) + caster.equipItem(boundArrow, TRUE, TRUE) +endEVENT + +EVENT onLoad() +; debug.trace("Bound Bow caught Cell Attach") + if !(getCasterActor().hasMagicEffect(BoundBowFFSelf)) +; debug.trace("Bound Bow - Cell Attached, script active, but effect not found on "+getCasterActor()) + dispel() + endif +endEVENT + +EVENT OnEffectFinish(Actor Target, Actor Caster) +; debug.trace("Bound Bow - Effect Finishing, remove any bound arrows") + caster.removeitem(boundArrow,caster.getItemCount(boundArrow),TRUE) +endEVENT + diff --git a/source/scripts/briarheartingredientscript.psc b/source/scripts/briarheartingredientscript.psc new file mode 100644 index 00000000..230e581a --- /dev/null +++ b/source/scripts/briarheartingredientscript.psc @@ -0,0 +1,57 @@ +Scriptname briarheartIngredientScript extends ObjectReference +{Script handles the visuals of a briarheart going in or out of a briarheart forsworn} +armor property ArmorBriarHeartEmpty auto +armor property ArmorBriarHeart auto +spell property dunReanimateSelf auto + +EVENT OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer) + + if (akOldContainer as actor) + +; ; debug.trace("Briarheart: Handle removal from an actor") + actor oldHost = (akOldContainer as actor) + if oldHost.isEquipped(armorBriarHeart) + if oldHost.getItemCount(armorBriarHeartEmpty) < 1 + oldHost.additem(armorBriarHeartEmpty, 1) + endif + if !oldHost.isDead() +; ; debug.trace("Briarheart: if I was a living Briarheart, then kill me and blame it on whomever took my heart.:") + oldHost.kill(akNewContainer as actor) + endif + while utility.isInMenuMode() + utility.wait(0.1) + endWhile + + oldHost.equipItem(armorBriarHeartEmpty, TRUE, TRUE) + oldHost.unequipItem(armorBriarHeart, TRUE, TRUE) + endif + endif + + if (akNewContainer as actor) +; debug.trace("DEBUG LiNE 28") +; ; debug.trace("Briarheart: my new container is an actor. See if it's a briarheart w/o a heart") + actor newHost = (akNewContainer as actor) + + if newHost.isEquipped(armorBriarHeartEmpty) + if newHost.getItemCount(ArmorBriarHeart) < 1 + newHost.addItem(armorBriarHeart,1) + endif + + if newHost.isDead() + ; if the briarheart was dead, resurrect it. + ;dunReanimateSelf.cast(newHost,newHost) + + while utility.isInMenuMode() + utility.wait(0.1) + endWhile + + if !newHost.isEquipped(armorBriarHeart) + newHost.equipItem (armorBriarHeart, TRUE, TRUE) + endif + + ;newHost.unequipItem (armorBriarHeartEmpty, TRUE, TRUE) + endif + endif + endif + +endEVENT diff --git a/source/scripts/carryactorscript.psc b/source/scripts/carryactorscript.psc new file mode 100644 index 00000000..931c6e23 --- /dev/null +++ b/source/scripts/carryactorscript.psc @@ -0,0 +1,105 @@ +Scriptname CarryActorScript extends ObjectReference +{Script for actors who carry items around} + +MiscObject Property CarryItemMisc Auto +{item being carried - MiscObject} + +int Property CarryItemMiscCount = 1 Auto +{how many items to drop when interrupted} + +Potion Property CarryItemPotion Auto +{potion item being carried - Potion (food)} + +int Property CarryItemPotionCount = 1 Auto +{how many items to drop when interrupted } + +Ingredient Property CarryItemIngredient Auto +{ingredient item being carried - Ingredients (flowers etc.)} + +int Property CarryItemIngredientCount = 1 Auto +{how many items to drop when interrupted } + +Idle Property StopCarryingEvent Auto +{event to send when stopping carry} + +;set to true when item is being carried} +bool bCarryFlag = false + +; all state changes for this actor go through this function +; call begin in OnBegin package block +function ChangeCarryState(bool bBeginCarrying, bool bDropItem = false) +; ; debug.trace(self + " ChangeCarryState") + if bBeginCarrying +; ; debug.trace(self + " ChangeCarryState BEGIN") + bCarryFlag = 1 + else + ; if I'm currently carrying something, see if I should drop it + if bCarryFlag && bDropItem +; ; debug.trace(self + " ChangeCarryState: DROP") + + ; I was interrupted, drop the items + RemoveCarriedItems(bDrop = true) + else +; ; debug.trace(self + " ChangeCarryState: NO DROP") + ; remove from inventory just to be safe + RemoveCarriedItems() + endif + ; I'm not carrying anything any more + bCarryFlag = 0 + ; get rid of anim object + Actor selfActor = (self as ObjectReference) as Actor + selfActor.PlayIdle(StopCarryingEvent) + endif +endFunction + +Event OnCombatStateChanged(Actor akTarget, int aeCombatState) + if bCarryFlag + ; drop what I'm carrying + ChangeCarryState(false, true) + endif +endEvent + +; adds carried items to inventory +function AddCarriedItems() + if CarryItemMisc + AddItem(CarryItemMisc, CarryItemMiscCount) + endif + if CarryItemPotion + AddItem(CarryItemPotion, CarryItemPotionCount) + endif + if CarryItemIngredient + AddItem(CarryItemIngredient, CarryItemIngredientCount) + endif +endFunction + +; removes all carried items from inventory, optionally dropping them into the world +function RemoveCarriedItems(bool bDrop = false) + if bDrop + DropCarriedItems(CarryItemMisc, CarryItemMiscCount) + DropCarriedItems(CarryItemPotion, CarryItemPotionCount) + DropCarriedItems(CarryItemIngredient, CarryItemIngredientCount) + else + if CarryItemMisc + RemoveItem(CarryItemMisc, CarryItemMiscCount) + endif + if CarryItemPotion + RemoveItem(CarryItemPotion, CarryItemPotionCount) + endif + if CarryItemIngredient + RemoveItem(CarryItemIngredient, CarryItemIngredientCount) + endif + endif +endFunction + +function DropCarriedItems(Form ItemToDrop, int iDropCount) + if iDropCount == 0 || ItemToDrop == None + return + endif + + int itemsLeft = iDropCount + while itemsLeft > 0 + DropObject(ItemToDrop, 1) + itemsLeft = itemsLeft - 1 + endWhile + +endFunction diff --git a/source/scripts/carryfurniturescript.psc b/source/scripts/carryfurniturescript.psc new file mode 100644 index 00000000..640f6772 --- /dev/null +++ b/source/scripts/carryfurniturescript.psc @@ -0,0 +1,54 @@ +Scriptname CarryFurnitureScript extends ObjectReference +{script for furniture used for carry animations +(handles both pick up and put down) +} + +MiscObject Property CarryObject Auto +{what they pick up and drop } + +int Property CarryObjectCount = 1 Auto +{how many to pick up and drop} + +Event OnLoad() + ; clear everything + gotoState("normal") +endEvent + +auto STATE normal +Event OnActivate(ObjectReference akActionRef) + gotoState("busy") +; debug.trace(self + "OnActivate by " + akActionRef) + RegisterForAnimationEvent(akActionRef, "AddToInventory") + RegisterForAnimationEvent(akActionRef, "RemoveFromInventory") + ; possibly obsolete? +; RegisterForAnimationEvent(akActionRef, "IdleFurnitureExit") +endEvent +endState + +STATE busy + ; waiting for animation event +endState + +Event OnAnimationEvent(ObjectReference akSource, string asEventName) +; debug.trace(self + ": animation event received=" + asEventName) + if asEventName == "AddToInventory" + ; add only if we need more + while akSource.GetItemCount(CarryObject) < CarryObjectCount + akSource.AddItem(CarryObject, 1) + endWhile + gotoState("normal") + UnregisterForEvents(akSource) + elseif asEventName == "RemoveFromInventory" + akSource.RemoveItem(CarryObject,CarryObjectCount ) + gotoState("normal") + UnregisterForEvents(akSource) + endif +endEvent + +function UnregisterForEvents(ObjectReference akSource) + ; centralize this + UnRegisterForAnimationEvent(akSource, "AddToInventory") + UnRegisterForAnimationEvent(akSource, "RemoveFromInventory") +; UnRegisterForAnimationEvent(akSource, "IdleFurnitureExit") +endFunction + diff --git a/source/scripts/companionshousekeepingscript.psc b/source/scripts/companionshousekeepingscript.psc new file mode 100644 index 00000000..ede8f197 --- /dev/null +++ b/source/scripts/companionshousekeepingscript.psc @@ -0,0 +1,1231 @@ +Scriptname CompanionsHousekeepingScript extends Quest Conditional + +Faction property CompanionsFaction auto + +MiscObject property GoldReward auto +int property GoldRewardMinorAmount auto +int property GoldRewardModerateAmount auto +int property GoldRewardMajorAmount auto + +; for introductory loop +bool property PlayerWalkedAwayDuringKVScene auto conditional +bool property PlayerWalkedAwayDuringSAScene auto conditional +bool property PlayerIgnoredVilkasOutside auto conditional +bool property PlayerMetKodlak auto conditional +bool property PlayerMetVilkas auto conditional +bool property PlayerMetEorlund auto conditional +bool property PlayerMetAela auto conditional +bool property PlayerMetSkjor auto conditional +bool property PlayerMetFarkas auto conditional +bool property FarkasLastSceneStarted auto conditional +bool property AelaShouldForceGreet auto conditional +bool property EorlundShouldForceGreet auto conditional +bool property FarkasSceneGo auto conditional +Quest property TrainingQuest auto +ReferenceAlias property VilkasSword auto +ReferenceAlias property VilkasQuestSword auto +bool property VilkasHasHisSwordBack auto conditional +bool Property PlayerMetCompanionsAtGiant auto conditional +bool Property PlayerHelpedCompanionsAtGiant auto conditional + +; got reward for full joining +bool Property GotWeaponReward auto conditional +bool Property EorlundToldAboutSkyforge auto conditional + +; the person following you (mostly for dialogue conditions) +ReferenceAlias Property CurrentFollower auto + +; so we can wrangle your followers +DialogueFollowerScript Property FollowerScript auto +GlobalVariable Property PlayerFollowerCount auto +DarkBrotherhood Property DBScript auto +Actor Property CiceroFollower auto +Actor Property DBInitiateFollower1 auto +Actor Property DBInitiateFollower2 auto + +; the circle (tm) + kodlak (collect all five) +ReferenceAlias property Skjor auto +ReferenceAlias property Aela auto +ReferenceAlias property Farkas auto +ReferenceAlias property Vilkas auto +ReferenceAlias property Kodlak auto + +; other jerks +ReferenceAlias Property Athis auto +ReferenceAlias Property Njada auto +ReferenceAlias Property Ria auto +ReferenceAlias Property Torvar auto + +; not technically a companion, but he's still cool +ReferenceAlias Property Eorlund auto + +; the faction for trainers to get put into when the player joins +Faction Property TrainerFaction auto + +; that guy (or gal) who follows you +ReferenceAlias property TrialObserver auto + +; the weapon that we'll give to Vilkas +Weapon property VilkasWeapon auto + +; setting up Eorlund to sell you Companions gear +LeveledItem Property CompanionsArmor auto +LeveledItem Property SkyforgeSteelWeapons auto +ObjectReference Property EorlundVendorChest auto +GlobalVariable Property GearChance auto + +; naughty naughty +bool property PlayerThievingAndNotPaying auto conditional +int property PlayerThievingThreshold auto conditional + +; to shut them up when there are more important things going on +ReferenceAlias Property GenericDialogueSuppressor1 auto +ReferenceAlias Property GenericDialogueSuppressor2 auto +ReferenceAlias Property GenericDialogueSuppressor3 auto +ReferenceAlias Property GenericDialogueSuppressor4 auto + +; track whether the player currently has werewolf ability +bool Property PlayerHasBeastBlood = false auto conditional +GlobalVariable Property PlayerIsWerewolf auto + ; gets set true when you join (so we can still debug the werewolf transform) + bool Property PlayerIsWerewolfVirgin = false auto conditional + +; so Skjor can let you in to the Underforge before you're a werewolf +bool Property TempUnderforgeAccess = false auto conditional + +Quest Property WerewolfChangeTrackingQuest auto +Spell Property WerewolfImmunity auto +Spell Property BeastForm auto +; FIX FOR 81462 +Spell Property HircinesRingPower auto +; END FIX FOR 81462 + +Race Property PlayerOriginalRace auto + +Race Property ArgonianRace auto +Race Property ArgonianRaceVampire auto +Race Property BretonRace auto +Race Property BretonRaceVampire auto +Race Property DarkElfRace auto +Race Property DarkElfRaceVampire auto +Race Property HighElfRace auto +Race Property HighElfRaceVampire auto +Race Property ImperialRace auto +Race Property ImperialRaceVampire auto +Race Property KhajiitRace auto +Race Property KhajiitRaceVampire auto +Race Property NordRace auto +Race Property NordRaceVampire auto +Race Property OrcRace auto +Race Property OrcRaceVampire auto +Race Property RedguardRace auto +Race Property RedguardRaceVampire auto +Race Property WoodElfRace auto +Race Property WoodElfRaceVampire auto + +Shout Property CurrentHowl auto +WordOfPower Property CurrentHowlWord1 auto +WordOfPower Property CurrentHowlWord2 auto +WordOfPower Property CurrentHowlWord3 auto + +;;; quest tracking from here down ;;; +int property RadiantQuestsDone auto conditional +int property RadiantQuestsDoneInCurrentSegment auto conditional +ReferenceAlias property RadiantQuestgiver auto +Faction Property CurrentFollowerFaction auto + +int Property C04MinLevel auto ; because there are Hagravens involved + +CompanionsRadiantQuest Property AelaCurrentQuest auto +CompanionsRadiantQuest Property VilkasCurrentQuest auto +CompanionsRadiantQuest Property FarkasCurrentQuest auto +CompanionsRadiantQuest Property SkjorCurrentQuest auto + +CompanionsRadiantQuest Property AelaNextQuest auto +CompanionsRadiantQuest Property VilkasNextQuest auto +CompanionsRadiantQuest Property FarkasNextQuest auto +CompanionsRadiantQuest Property SkjorNextQuest auto + +Keyword property AelaRadiantKeyword auto +Keyword property SkjorRadiantKeyword auto +Keyword property VilkasRadiantKeyword auto +Keyword property FarkasRadiantKeyword auto +Keyword property ReconRadiantKeyword auto + +bool property RadiantAelaBlock auto conditional +bool property RadiantSkjorBlock auto conditional +bool property RadiantFarkasBlock auto conditional +bool property RadiantVilkasBlock auto conditional + +Quest Property RadiantMiscObjQuest auto +bool property StoryQuestIsRunning auto conditional +bool property RadiantQuestAccepted auto conditional +bool property RadiantQuestFinished auto conditional +bool property IsCurrentSilverHandTarget auto conditional +int property LastRadiantQuestDoneIndex auto conditional + +bool property AelaInReconMode auto conditional +bool property DoneReconQuestForAela auto conditional +ObjectReference property QuestgiverStandMarker auto conditional + +int property RadiantQuestsUntilC01 auto +int property RadiantQuestsUntilC03 auto +int property RadiantQuestsUntilC04 auto + +CompanionsStoryQuest property C01 auto +CompanionsStoryQuest property C02 auto +CompanionsStoryQuest property C03 auto +CompanionsStoryQuest property C04 auto +CompanionsStoryQuest property C05 auto +CompanionsStoryQuest property C06 auto + +; CR12 persistent tracking +int Property TotemsFound auto conditional +bool Property AelaIsConfused auto conditional + +; CR13 persistent tracking +bool Property VilkasHasBeastBlood auto conditional +bool Property FarkasHasBeastBlood auto conditional + +;; Radiant Quests +; grunt work +CompanionsRadiantQuest property CR01 auto ; a beast loose in someone's house +CompanionsRadiantQuest property CR02 auto ; beasts in a den near town harassing people +CompanionsRadiantQuest property CR03 auto ; collect pelts +CompanionsRadiantQuest property CR04 auto ; intimidation missions +CompanionsRadiantQuest property CR05 auto ; clear a dungeon +CompanionsRadiantQuest property CR06 auto ; family heirloom +; "real" quests +CompanionsRadiantQuest property CR07 auto ; capture criminals +CompanionsRadiantQuest property CR08 auto ; rescue people +; silver hand quests with Aela +CompanionsRadiantQuest property CR09 auto ; assasinate lieutenants +CompanionsRadiantQuest property CR10 auto ; steal plans +CompanionsRadiantQuest property CR11 auto ; retrieve pieces of blade +CompanionsRadiantQuest property CR12 auto ; wipe out camps +; leader work +CompanionsRadiantQuest property CR13 auto ; curing vilkas/farkas +CompanionsRadiantQuest property CR14 auto ; let a newbie in + +CompanionsStoryQuest property CurrentStoryQuest auto + +int property FavoriteQuestgiver auto conditional + ; 0 --> None (default behavior defined in quest) + ; 1 --> Aela + ; 3 --> Vilkas + ; 2 --> Farkas + ; 4 --> Skjor +bool Property AelaIsObserver auto conditional +bool Property FarkasIsObserver auto conditional +int property AelaQuests auto +int property FarkasQuests auto +int property VilkasQuests auto +int property SkjorQuests auto + +;; location tracking for reservations +LocationAlias Property DustmansCairn auto +LocationAlias Property GallowsRock auto +LocationAlias Property YsgramorsTomb auto + + +; Quest Designer needs arrays badly. Quest Designer is about to die. +CompanionsRadiantQuest Function GetRadiantQuestFromIndex(int questIndex) + if (questIndex == 1) + return CR01 + elseif (questIndex == 2) + return CR02 + elseif (questIndex == 3) + return CR03 + elseif (questIndex == 4) + return CR04 + elseif (questIndex == 5) + return CR05 + elseif (questIndex == 6) + return CR06 + elseif (questIndex == 7) + return CR07 + elseif (questIndex == 8) + return CR08 + elseif (questIndex == 9) + return CR09 + elseif (questIndex == 10) + return CR10 + elseif (questIndex == 11) + return CR11 + elseif (questIndex == 12) + return CR12 + elseif (questIndex == 13) + return CR13 + elseif (questIndex == 14) + return CR14 + else + return None + endif +EndFunction + +int Function GetIndexFromRadiantQuest(Quest rQuest) + if (rQuest == CR01) + return 1 + elseif (rQuest == CR02) + return 2 + elseif (rQuest == CR03) + return 3 + elseif (rQuest == CR04) + return 4 + elseif (rQuest == CR05) + return 5 + elseif (rQuest == CR06) + return 6 + elseif (rQuest == CR07) + return 7 + elseif (rQuest == CR08) + return 8 + elseif (rQuest == CR09) + return 9 + elseif (rQuest == CR10) + return 10 + elseif (rQuest == CR11) + return 11 + elseif (rQuest == CR12) + return 12 + elseif (rQuest == CR13) + return 13 + elseif (rQuest == CR14) + return 14 + else + return 0 + endif +EndFunction + + +Function OnInit() + ; PlayerJoin() ; for debugging, usually commented out +EndFunction + +Function SetUpCompanions() +; Debug.Trace("C00: Waiting to set up Companions.") + Utility.Wait(60) ; giving other quests the chance to finish their reservations + ; (very conservative time buffer, but chargen takes a while, + ; so let's be safe) + +; Debug.Trace("C00: Setting up Companions...") + + RadiantQuestsDone = 0 + StoryQuestIsRunning = False + RadiantQuestAccepted = False + RadiantQuestFinished = False + + AelaCurrentQuest = None + VilkasCurrentQuest = None + FarkasCurrentQuest = None + SkjorCurrentQuest = None + + AelaNextQuest = None + VilkasNextQuest = None + FarkasNextQuest = None + SkjorNextQuest = None + + RadiantAelaBlock = False + RadiantFarkasBlock = False + RadiantSkjorBlock = False + RadiantVilkasBlock = False + + ; do this twice to queue up two quests + CycleRadiantQuests() + ; while (\ + ; (SkjorCurrentQuest == None || !SkjorCurrentQuest.GetStageDone(1)) \ + ; && (AelaCurrentQuest == None || !AelaCurrentQuest.GetStageDone(1)) \ + ; && (FarkasCurrentQuest == None || !FarkasCurrentQuest.GetStageDone(1)) \ + ; && (VilkasCurrentQuest == None || !VilkasCurrentQuest.GetStageDone(1)) \ + ; ) +; ; Debug.Trace("C00: Waiting on RQ cycle...") + ; Utility.Wait(0.1) + ; endwhile + CycleRadiantQuests() + + CurrentStoryQuest = None + +; Debug.Trace("C00: Setup done; setting stage 1.") + SetStage(1) +EndFunction + +Function PlayerJoin() +; Debug.Trace("C00: Player joined Companions.") + if (Game.GetPlayer().IsInFaction(CompanionsFaction)) + return + endif + + Game.GetPlayer().AddToFaction(CompanionsFaction) + + ; start misc pointer for radiant quests + RadiantMiscObjQuest.Start() + + ; allow trainers + Athis.GetActorReference().AddToFaction(TrainerFaction) + Aela.GetActorReference().AddToFaction(TrainerFaction) + Njada.GetActorReference().AddToFaction(TrainerFaction) + Vilkas.GetActorReference().AddToFaction(TrainerFaction) + Eorlund.GetActorReference().AddToFaction(TrainerFaction) + Farkas.GetActorReference().AddToFaction(TrainerFaction) + + ; set up the spell tracking so the first time you cast it doesn't count + PlayerIsWerewolfVirgin = true + + ; get player's race so we have it permanently for werewolf switch back + PlayerOriginalRace = Game.GetPlayer().GetRace() +; Debug.Trace("CSQ: Storing player's race as " + PlayerOriginalRace) + + if (PlayerOriginalRace == ArgonianRaceVampire) +; Debug.Trace("CSQ: Player was Argonian Vampire; storing as Argonian.") + PlayerOriginalRace = ArgonianRace + elseif (PlayerOriginalRace == BretonRaceVampire) +; Debug.Trace("CSQ: Player was Breton Vampire; storing as Breton.") + PlayerOriginalRace = BretonRace + elseif (PlayerOriginalRace == DarkElfRaceVampire) +; Debug.Trace("CSQ: Player was Dark Elf Vampire; storing as Dark Elf.") + PlayerOriginalRace = DarkElfRace + elseif (PlayerOriginalRace == HighElfRaceVampire) +; Debug.Trace("CSQ: Player was High Elf Vampire; storing as High Elf.") + PlayerOriginalRace = HighElfRace + elseif (PlayerOriginalRace == ImperialRaceVampire) +; Debug.Trace("CSQ: Player was Imperial Vampire; storing as Imperial.") + PlayerOriginalRace = ImperialRace + elseif (PlayerOriginalRace == KhajiitRaceVampire) +; Debug.Trace("CSQ: Player was Khajiit Vampire; storing as Khajiit.") + PlayerOriginalRace = KhajiitRace + elseif (PlayerOriginalRace == NordRaceVampire) +; Debug.Trace("CSQ: Player was Nord Vampire; storing as Nord.") + PlayerOriginalRace = NordRace + elseif (PlayerOriginalRace == OrcRaceVampire) +; Debug.Trace("CSQ: Player was Orc Vampire; storing as Orc.") + PlayerOriginalRace = OrcRace + elseif (PlayerOriginalRace == RedguardRaceVampire) +; Debug.Trace("CSQ: Player was Redguard Vampire; storing as Redguard.") + PlayerOriginalRace = RedguardRace + elseif (PlayerOriginalRace == WoodElfRaceVampire) +; Debug.Trace("CSQ: Player was Wood Elf Vampire; storing as Wood Elf.") + PlayerOriginalRace = WoodElfRace + endif + +; Debug.Trace("CSQ: Storing player's race as " + PlayerOriginalRace) + + ; achievements YAY + Game.AddAchievement(9) +EndFunction + +Function OpenSkyforge() + ; set up Eorlund to sell you stuff + GearChance.SetValueInt(0) + + ; add them right now in case you run up + EorlundVendorChest.AddItem(CompanionsArmor) + EorlundVendorChest.AddItem(SkyforgeSteelWeapons) +EndFunction + +; super specialized +Function GiveVilkasBackHisSword() + ObjectReference vs = VilkasSword.GetReference() + ; make sure it's been cleared as a quest item + VilkasQuestSword.Clear() + VilkasSword.Clear() + + Eorlund.GetReference().RemoveItem(vs) + + Vilkas.GetReference().AddItem(VilkasWeapon) + + VilkasHasHisSwordBack = True +EndFunction + +Function CycleRadiantQuests() +; Debug.Trace("CRQ: Cycling radiant quests...") + ; just in case some idjit (i.e. me) unblocked a dead questgiver + if (Aela.GetActorReference().IsDead()) + if (AelaCurrentQuest != None) + AelaCurrentQuest.Stop() + AelaCurrentQuest = None + endif + if (AelaNextQuest != None) + AelaNextQuest.Stop() + AelaNextQuest = None + endif + RadiantAelaBlock = True + endif + if (Farkas.GetActorReference().IsDead()) + if (FarkasCurrentQuest != None) + FarkasCurrentQuest.Stop() + FarkasCurrentQuest = None + endif + if (FarkasNextQuest != None) + FarkasNextQuest.Stop() + FarkasNextQuest = None + endif + RadiantFarkasBlock = True + endif + if (Vilkas.GetActorReference().IsDead()) + if (VilkasCurrentQuest != None) + VilkasCurrentQuest.Stop() + VilkasCurrentQuest = None + endif + if (VilkasNextQuest != None) + VilkasNextQuest.Stop() + VilkasNextQuest = None + endif + RadiantVilkasBlock = True + endif + if (Skjor.GetActorReference().IsDead()) + if (SkjorCurrentQuest != None) + SkjorCurrentQuest.Stop() + SkjorCurrentQuest = None + endif + if (SkjorNextQuest != None) + SkjorNextQuest.Stop() + SkjorNextQuest = None + endif + RadiantSkjorBlock = True + endif + + ; lord, so much duplicated code here... this grew "organically" and is now hideous. + ; do not look here for examples of good tidy code. + if (!RadiantAelaBlock) + if (AelaCurrentQuest && AelaNextQuest && !AelaCurrentQuest.IsAccepted) + ; current quest not accepted, and we have a good next choice lined up -- swap + AelaCurrentQuest.Stop() + AelaCurrentQuest = AelaNextQuest + AelaNextQuest = None + AelaCurrentQuest.IsActive = True + elseif (AelaCurrentQuest && AelaCurrentQuest.Premature) + ; no better option, but we're trying to cycle out a prematurely ended quest, + ; so make it happen + AelaCurrentQuest.Stop() + AelaCurrentQuest = AelaNextQuest + AelaNextQuest = None + if (AelaCurrentQuest != None) + AelaCurrentQuest.IsActive = True + else + ; hope for the best at the next pick + endif + elseif (!AelaCurrentQuest && AelaNextQuest) + ; no current quest for whatever effed up reason, but got something in the + ; chamber, so fire. + AelaCurrentQuest = AelaNextQuest + AelaNextQuest = None + AelaCurrentQuest.IsActive = True + elseif (AelaNextQuest && AelaNextQuest != AelaCurrentQuest) + ; I don't even know why this is here anymore, but it is. + AelaNextQuest.Stop() + AelaNextQuest = None + elseif (AelaCurrentQuest && AelaCurrentQuest.GetStage() >= 200) + ; in case something got stuck someplace, make sure this eventually + ; gets cycled out + AelaCurrentQuest.Stop() + if (AelaNextQuest != None) + AelaCurrentQuest = AelaNextQuest + AelaNextQuest = None + AelaCurrentQuest.IsActive = True + else + AelaCurrentQuest = None + endif + endif + PickRadiantQuest(Aela.GetActorReference()) + elseif (AelaCurrentQuest && AelaCurrentQuest.GetStage() >= 200) + ; even if there's a block, cycle out done quests + AelaCurrentQuest.Stop() + if (AelaNextQuest != None) + AelaCurrentQuest = AelaNextQuest + AelaNextQuest = None + else + AelaCurrentQuest = None + endif + endif + if (!RadiantFarkasBlock) + if (FarkasCurrentQuest && FarkasNextQuest && !FarkasCurrentQuest.IsAccepted) + ; current quest not accepted, and we have a good next choice lined up -- swap + FarkasCurrentQuest.Stop() + FarkasCurrentQuest = FarkasNextQuest + FarkasNextQuest = None + FarkasCurrentQuest.IsActive = True + elseif (FarkasCurrentQuest && FarkasCurrentQuest.Premature) + ; no better option, but we're trying to cycle out a prematurely ended quest, + ; so make it happen + FarkasCurrentQuest.Stop() + FarkasCurrentQuest = FarkasNextQuest + FarkasNextQuest = None + if (FarkasCurrentQuest != None) + FarkasCurrentQuest.IsActive = True + else + ; hope for the best at the next pick + endif + elseif (!FarkasCurrentQuest && FarkasNextQuest) + ; no current quest for whatever effed up reason, but got something in the + ; chamber, so fire. + FarkasCurrentQuest = FarkasNextQuest + FarkasNextQuest = None + FarkasCurrentQuest.IsActive = True + elseif (FarkasNextQuest && FarkasNextQuest != FarkasCurrentQuest) + ; I don't even know why this is here anymore, but it is. + FarkasNextQuest.Stop() + FarkasNextQuest = None + elseif (FarkasCurrentQuest && FarkasCurrentQuest.GetStage() >= 200) + ; in case something got stuck someplace, make sure this eventually + ; gets cycled out + FarkasCurrentQuest.Stop() + if (FarkasNextQuest != None) + FarkasCurrentQuest = FarkasNextQuest + FarkasNextQuest = None + FarkasCurrentQuest.IsActive = True + else + FarkasCurrentQuest = None + endif + endif + PickRadiantQuest(Farkas.GetActorReference()) + elseif (FarkasCurrentQuest && FarkasCurrentQuest.GetStage() >= 200) + ; even if there's a block, cycle out done quests + FarkasCurrentQuest.Stop() + if (FarkasNextQuest != None) + FarkasCurrentQuest = FarkasNextQuest + FarkasNextQuest = None + else + FarkasCurrentQuest = None + endif + endif + if (!RadiantVilkasBlock) + if (VilkasCurrentQuest && VilkasNextQuest && !VilkasCurrentQuest.IsAccepted) + ; current quest not accepted, and we have a good next choice lined up -- swap + VilkasCurrentQuest.Stop() + VilkasCurrentQuest = VilkasNextQuest + VilkasNextQuest = None + VilkasCurrentQuest.IsActive = True + elseif (VilkasCurrentQuest && VilkasCurrentQuest.Premature) + ; no better option, but we're trying to cycle out a prematurely ended quest, + ; so make it happen + VilkasCurrentQuest.Stop() + VilkasCurrentQuest = VilkasNextQuest + VilkasNextQuest = None + if (VilkasCurrentQuest != None) + VilkasCurrentQuest.IsActive = True + else + ; hope for the best at the next pick + endif + elseif (!VilkasCurrentQuest && VilkasNextQuest) + ; no current quest for whatever effed up reason, but got something in the + ; chamber, so fire. + VilkasCurrentQuest = VilkasNextQuest + VilkasNextQuest = None + VilkasCurrentQuest.IsActive = True + elseif (VilkasNextQuest && VilkasNextQuest != VilkasCurrentQuest) + ; I don't even know why this is here anymore, but it is. + VilkasNextQuest.Stop() + VilkasNextQuest = None + elseif (VilkasCurrentQuest && VilkasCurrentQuest.GetStage() >= 200) + ; in case something got stuck someplace, make sure this eventually + ; gets cycled out + VilkasCurrentQuest.Stop() + if (VilkasNextQuest != None) + VilkasCurrentQuest = VilkasNextQuest + VilkasNextQuest = None + VilkasCurrentQuest.IsActive = True + else + VilkasCurrentQuest = None + endif + endif + PickRadiantQuest(Vilkas.GetActorReference()) + elseif (VilkasCurrentQuest && VilkasCurrentQuest.GetStage() >= 200) + ; even if there's a block, cycle out done quests + VilkasCurrentQuest.Stop() + if (VilkasNextQuest != None) + VilkasCurrentQuest = VilkasNextQuest + VilkasNextQuest = None + else + VilkasCurrentQuest = None + endif + endif + if (!RadiantSkjorBlock) + if (SkjorCurrentQuest && SkjorNextQuest && !SkjorCurrentQuest.IsAccepted) + ; current quest not accepted, and we have a good next choice lined up -- swap + SkjorCurrentQuest.Stop() + SkjorCurrentQuest = SkjorNextQuest + SkjorNextQuest = None + SkjorCurrentQuest.IsActive = True + elseif (SkjorCurrentQuest && SkjorCurrentQuest.Premature) + ; no better option, but we're trying to cycle out a prematurely ended quest, + ; so make it happen + SkjorCurrentQuest.Stop() + SkjorCurrentQuest = SkjorNextQuest + SkjorNextQuest = None + if (SkjorCurrentQuest != None) + SkjorCurrentQuest.IsActive = True + else + ; hope for the best at the next pick + endif + elseif (!SkjorCurrentQuest && SkjorNextQuest) + ; no current quest for whatever effed up reason, but got something in the + ; chamber, so fire. + SkjorCurrentQuest = SkjorNextQuest + SkjorNextQuest = None + SkjorCurrentQuest.IsActive = True + elseif (SkjorNextQuest && SkjorNextQuest != SkjorCurrentQuest) + ; I don't even know why this is here anymore, but it is. + SkjorNextQuest.Stop() + SkjorNextQuest = None + elseif (SkjorCurrentQuest && SkjorCurrentQuest.GetStage() >= 200) + ; in case something got stuck someplace, make sure this eventually + ; gets cycled out + SkjorCurrentQuest.Stop() + if (SkjorNextQuest != None) + SkjorCurrentQuest = SkjorNextQuest + SkjorNextQuest = None + SkjorCurrentQuest.IsActive = True + else + SkjorCurrentQuest = None + endif + endif + PickRadiantQuest(Skjor.GetActorReference()) + elseif (SkjorCurrentQuest && SkjorCurrentQuest.GetStage() >= 200) + ; even if there's a block, cycle out done quests + SkjorCurrentQuest.Stop() + if (SkjorNextQuest != None) + SkjorCurrentQuest = SkjorNextQuest + SkjorNextQuest = None + else + SkjorCurrentQuest = None + endif + endif + + + ; 77298: Fixing situation where next quests were flagged premature + ; and not cleared out before player was able to get at them. + if (AelaNextQuest != None && AelaNextQuest.Premature == True) + AelaNextQuest.Stop() + AelaNextQuest = None + endif + if (FarkasNextQuest != None && FarkasNextQuest.Premature == True) + FarkasNextQuest.Stop() + FarkasNextQuest = None + endif + if (VilkasNextQuest != None && VilkasNextQuest.Premature == True) + VilkasNextQuest.Stop() + VilkasNextQuest = None + endif + if (SkjorNextQuest != None && SkjorNextQuest.Premature == True) + SkjorNextQuest.Stop() + SkjorNextQuest = None + endif + ; END 77298 +EndFunction + +Function PickRadiantQuest(Actor questgiver) +; Debug.Trace("CRQ: Trying to pick radiant quest for " + questgiver) + + if (questgiver.IsDead()) +; Debug.Trace("CRQ: Questgiver " + questgiver + " is dead; skipping radiant selection.") + return + endif + + if (questgiver == Aela.GetActorReference()) + Keyword ark = AelaRadiantKeyword + if ( AelaInReconMode ) + ark = ReconRadiantKeyword + endif + ark.SendStoryEvent() + elseif (questgiver == Skjor.GetActorReference()) + SkjorRadiantKeyword.SendStoryEvent() + elseif (questgiver == Vilkas.GetActorReference()) + VilkasRadiantKeyword.SendStoryEvent() + elseif (questgiver == Farkas.GetActorReference()) + FarkasRadiantKeyword.SendStoryEvent() + endif +EndFunction + +Function RegisterRadiantQuest(CompanionsRadiantQuest newRadiant) + Actor qg = newRadiant.Questgiver.GetActorReference() + if (qg == None || newRadiant.IsRegistered) + return ; we'll register when the story event comes through + endif + +; Debug.Trace("CRQ: Registering radiant quest -- " + newRadiant + " with questgiver -- " + qg) + + if (qg == Aela.GetActorReference()) + if (AelaCurrentQuest == None) + AelaCurrentQuest = newRadiant + AelaCurrentQuest.IsActive = True + elseif (!AelaCurrentQuest.IsActive) + AelaCurrentQuest.Stop() + AelaCurrentQuest = newRadiant + AelaCurrentQuest.IsActive = True + else + if (AelaNextQuest != None) + AelaNextQuest.Stop() + endif + AelaNextQuest = newRadiant + endif + elseif (qg == Skjor.GetActorReference()) + if (SkjorCurrentQuest == None) + SkjorCurrentQuest = newRadiant + SkjorCurrentQuest.IsActive = True + elseif (!SkjorCurrentQuest.IsActive) + SkjorCurrentQuest.Stop() + SkjorCurrentQuest = newRadiant + SkjorCurrentQuest.IsActive = True + else + if (SkjorNextQuest != None) + SkjorNextQuest.Stop() + endif + SkjorNextQuest = newRadiant + endif + elseif (qg == Vilkas.GetActorReference()) + if (VilkasCurrentQuest == None) + VilkasCurrentQuest = newRadiant + VilkasCurrentQuest.IsActive = True + elseif (!VilkasCurrentQuest.IsActive) + VilkasCurrentQuest.Stop() + VilkasCurrentQuest = newRadiant + VilkasCurrentQuest.IsActive = True + else + if (VilkasNextQuest != None) + VilkasNextQuest.Stop() + endif + VilkasNextQuest = newRadiant + endif + elseif (qg == Farkas.GetActorReference()) + if (FarkasCurrentQuest == None) + FarkasCurrentQuest = newRadiant + FarkasCurrentQuest.IsActive = True + elseif (!FarkasCurrentQuest.IsActive) + FarkasCurrentQuest.Stop() + FarkasCurrentQuest = newRadiant + FarkasCurrentQuest.IsActive = True + else + if (FarkasNextQuest != None) + FarkasNextQuest.Stop() + endif + FarkasNextQuest = newRadiant + endif + endif + + newRadiant.IsRegistered = true +EndFunction + +Function AcceptRadiantQuest(Actor questgiver, bool comesAlong) +; Debug.Trace("C00: Accepting radiant quest for " + questgiver + " -- comes along? " + comesAlong) + RadiantQuestAccepted = True + RadiantMiscObjQuest.SetObjectiveDisplayed(10, false) + + bool reg = true + + if (comesAlong) + reg = false + endif + if (questgiver == Aela.GetReference()) + if (AelaInReconMode && !DoneReconQuestForAela) + reg = false + endif + endif + if (questgiver.IsInFaction(CurrentFollowerFaction)) + reg = false + endif + + if (reg) +; Debug.Trace("C00: Registering " + questgiver + " as radiant questgiver.") + RadiantQuestgiver.ForceRefTo(questgiver) + endif + + ShutdownRadiantQuests(questgiver) +EndFunction + +Function ShutdownRadiantQuests(Actor exception = None) +; Debug.Trace("CRQ: Shutting down radiant quests, excepting " + exception) + if (exception != Aela.GetActorReference()) + RadiantAelaBlock = True + if (AelaCurrentQuest != None) + AelaCurrentQuest.IsActive = False + endif + endif + if (exception != Skjor.GetActorReference()) + RadiantSkjorBlock = True + if (SkjorCurrentQuest != None) + SkjorCurrentQuest.IsActive = False + endif + endif + if (exception != Vilkas.GetActorReference()) + RadiantVilkasBlock = True + if (VilkasCurrentQuest != None) + VilkasCurrentQuest.IsActive = False + endif + endif + if (exception != Farkas.GetActorReference()) + RadiantFarkasBlock = True + if (FarkasCurrentQuest != None) + FarkasCurrentQuest.IsActive = False + endif + endif + +; Debug.Trace("CRQ: Ensuring shutdown -- " + RadiantAelaBlock + " " + RadiantSkjorBlock + " " + RadiantVilkasBlock + " " + RadiantFarkasBlock) +EndFunction + +Function ShutdownRadiantQuestsFor(Actor busy) +; Debug.Trace("CRQ: Shutting down radiant quests for " + busy) + if (busy == Aela.GetActorReference()) + RadiantAelaBlock = True + if (AelaCurrentQuest != None) + AelaCurrentQuest.IsActive = False + endif + elseif (busy == Skjor.GetActorReference()) + RadiantSkjorBlock = True + if (SkjorCurrentQuest != None) + SkjorCurrentQuest.IsActive = False + endif + elseif (busy == Vilkas.GetActorReference()) + RadiantVilkasBlock = True + if (VilkasCurrentQuest != None) + VilkasCurrentQuest.IsActive = False + endif + elseif (busy == Farkas.GetActorReference()) + RadiantFarkasBlock = True + if (FarkasCurrentQuest != None) + FarkasCurrentQuest.IsActive = False + endif + endif + +; Debug.Trace("CRQ: Ensuring shutdown -- " + RadiantAelaBlock + " " + RadiantSkjorBlock + " " + RadiantVilkasBlock + " " + RadiantFarkasBlock) +EndFunction + +Function ReOpenAllRadiantQuests() +; Debug.Trace("CRQ: Reopening radiant quests.") + if (!Aela.GetActorReference().IsDead()) + RadiantAelaBlock = False + endif + if (!Skjor.GetActorReference().IsDead()) + RadiantSkjorBlock = False + endif + if (!Vilkas.GetActorReference().IsDead()) + RadiantVilkasBlock = False + endif + if (!Farkas.GetActorReference().IsDead()) + RadiantFarkasBlock = False + endif + + if (AelaCurrentQuest != None) + AelaCurrentQuest.IsActive = True + endif + if (SkjorCurrentQuest != None) + SkjorCurrentQuest.IsActive = True + endif + if (VilkasCurrentQuest != None) + VilkasCurrentQuest.IsActive = True + endif + if (FarkasCurrentQuest != None) + FarkasCurrentQuest.IsActive = True + endif +EndFunction + +bool __reconKicked = false + +; One off to kick Aela's recon radiant quests post C03 +Function KickOffReconQuests() + ; make sure this only gets called once + if (__reconKicked) + return + endif + +; Debug.Trace("CRQ: Starting recon quest sequence.") + + ; make sure some threaded interloper doesn't mess with us + RadiantAelaBlock = true + + ; clear out her existing radiant stuff + if (AelaCurrentQuest) + AelaCurrentQuest.Stop() + AelaCurrentQuest = None + endif + if (AelaNextQuest) + AelaNextQuest.Stop() + AelaNextQuest = None + endif + + AelaInReconMode = true + + bool keepTrying = true + while (keepTrying) +; Debug.Trace("CRQ: Trying to start specific recon quest...") + if (ReconRadiantKeyword.SendStoryEventAndWait()) + keepTrying = false + else +; Debug.Trace("CRQ: Failed to start recon quest; trying again.") + Utility.Wait(0.5) + endif + endwhile + + ReconRadiantKeyword.SendStoryEvent() + + RadiantAelaBlock = false +EndFunction + +int function CompleteRadiantQuest(CompanionsRadiantQuest rq) +; Debug.Trace("CRQ: Completing radiant quest: " + rq) + bool success = rq.Succeeded + + ; store the questgiver for checking later in this function + Actor qg = rq.Questgiver.GetActorReference() + + if (success) + ; increment questgiver count + if (qg == Aela.GetActorReference()) + AelaQuests += 1 + elseif (qg == Skjor.GetActorReference()) + SkjorQuests += 1 + elseif (qg == Vilkas.GetActorReference()) + VilkasQuests += 1 + elseif (qg == Farkas.GetActorReference()) + FarkasQuests += 1 + endif + + ; increment overall radiant quest count + RadiantQuestsDone += 1 + RadiantQuestsDoneInCurrentSegment += 1 + endif + + ; pay the player (even if not successful, there might be a midway reward) + Game.GetPlayer().AddItem(GoldReward, rq.RewardAmount) + + ; Mr. Book: SHUT IT DOWN! + ; rq.Stop() + rq.IsAccepted = False ; so it can get cleared with the cycle + ReOpenAllRadiantQuests() + + if (rq == CR13 || rq == CR14) + if (qg == Farkas.GetReference()) +; Debug.Trace("CRQ CR13|CR14: Blocking Farkas...") + ShutdownRadiantQuestsFor(Farkas.GetActorReference()) + else +; Debug.Trace("CRQ CR13|CR14: Blocking Vilkas...") + ShutdownRadiantQuestsFor(Vilkas.GetActorReference()) + endif + endif + + CycleRadiantQuests() + + ; update favorite questgiver + FavoriteQuestgiver = 0 + int fqgCount = 0 + if (AelaQuests > fqgCount) + FavoriteQuestgiver = 1 + fqgCount = AelaQuests + endif + if (FarkasQuests > fqgCount) + FavoriteQuestgiver = 2 + fqgCount = FarkasQuests + endif + if (VilkasQuests > fqgCount) + FavoriteQuestgiver = 3 + fqgCount = VilkasQuests + endif + if (SkjorQuests > fqgCount) + FavoriteQuestgiver = 4 + fqgCount = SkjorQuests + endif + + ; check to see if it's time to start the next story quest + bool startedStory = False + if (C01.GetStage() < 1) + ; count + if (RadiantQuestsDoneInCurrentSegment >= RadiantQuestsUntilC01) + StartStoryQuest(C01) + startedStory = True + endif + elseif (C03.GetStage() < 1) + ; count + if (RadiantQuestsDoneInCurrentSegment >= RadiantQuestsUntilC03) + StartStoryQuest(C03) + startedStory = True + endif + elseif (C04.GetStage() < 1) + ; count, also min level + if ( (RadiantQuestsDoneInCurrentSegment >= RadiantQuestsUntilC04) && (Game.GetPlayer().GetLevel() >= C04MinLevel) ) + StartStoryQuest(C04) + startedStory = True + endif + endif + + ; reset tracking + if (!startedStory) + RadiantMiscObjQuest.SetObjectiveDisplayed(10, true) + endif + RadiantQuestAccepted = False + RadiantQuestFinished = False + RadiantQuestgiver.Clear() + + ; reset tracking number + if (startedStory) + RadiantQuestsDoneInCurrentSegment = 0 + endif + + ; return total radiant quests done for Companions + return RadiantQuestsDone +endFunction + +Actor function GetFavoriteQuestgiver() + ; Shane wants arrays. + if (FavoriteQuestgiver == 1) + return Aela.GetActorReference() + elseif (FavoriteQuestgiver == 2) + return Farkas.GetActorReference() + elseif (FavoriteQuestgiver == 3) + return Vilkas.GetActorReference() + elseif (FavoriteQuestgiver == 4) + return Skjor.GetActorReference() + endif + + ; We haven't done any radiant quests -- this should only happen when + ; starting a story quest manually for testing purposes. Randomly pick + ; a favorite in that case. + + ; Lazily odded to only return Aela and Farkas + int randomQGIndex = Utility.RandomInt(1, 4) + if (randomQGIndex == 1) + AelaIsObserver = true + return Aela.GetActorReference() + elseif (randomQGIndex == 2) + FarkasIsObserver = true + return Farkas.GetActorReference() + elseif (randomQGIndex == 3) + AelaIsObserver = true + return Aela.GetActorReference() + elseif (randomQGIndex == 4) + FarkasIsObserver = true + return Farkas.GetActorReference() + endif + + ; We absolutely should never get to this point in the function; + ; it's a bug if we do. Still making sure we return *something* + ; just in case, and complaining to the log. +; Debug.Trace("CSQ: ERROR: Somehow got to the bottom of GetFavoriteQuestGiver function (C00).") + return Skjor.GetActorReference() +endFunction + +function StartStoryQuest(CompanionsStoryQuest storyToStart) + CurrentStoryQuest = storyToStart +; Debug.Trace("CSQ: Starting story quest: " + CurrentStoryQuest) + storyToStart.SetStage(1) + StoryQuestIsRunning = True + RadiantMiscObjQuest.SetObjectiveDisplayed(10, false) +endFunction + +function CompleteStoryQuest(CompanionsStoryQuest storyToEnd) +; Debug.Trace("CSQ: Ending " + storyToEnd) + + storyToEnd.Teardown() + storyToEnd.Stop() + while(storyToEnd.IsRunning()) +; Debug.Trace("CSQ: Waiting for quest to end: " + storyToEnd) + Utility.Wait(0.5) + endwhile + + CurrentStoryQuest = None + StoryQuestIsRunning = False + if ( (storyToEnd != C03) && (storyToEnd != C04) && (storyToEnd != C05) ) + RadiantMiscObjQuest.SetObjectiveDisplayed(10, true) + endif + if (storyToEnd == C02) + OpenSkyforge() + endif +endFunction + +Function AddHarbingerPerks() + Aela.GetActorReference().SetRelationshipRank(Game.GetPlayer(), 2) + Farkas.GetActorReference().SetRelationshipRank(Game.GetPlayer(), 2) + Vilkas.GetActorReference().SetRelationshipRank(Game.GetPlayer(), 2) + Athis.GetActorReference().SetRelationshipRank(Game.GetPlayer(), 2) + Ria.GetActorReference().SetRelationshipRank(Game.GetPlayer(), 2) + Njada.GetActorReference().SetRelationshipRank(Game.GetPlayer(), 2) + Torvar.GetActorReference().SetRelationshipRank(Game.GetPlayer(), 2) +EndFunction + +Function CurePlayer() +; Debug.Trace("WEREWOLF: Curing the player of lycanthropy.") + + ; turn you back if you're currently a werewolf + if (WerewolfChangeTrackingQuest.IsRunning() && WerewolfChangeTrackingQuest.GetStage() < 100) + WerewolfChangeTrackingQuest.SetStage(100) + endif + + ; take away spell and immunity + Game.GetPlayer().RemoveSpell(BeastForm) + Game.GetPlayer().RemoveSpell(WerewolfImmunity) + + ; FIX FOR 81462 + Game.GetPlayer().RemoveSpell(HircinesRingPower) + ; END FIX FOR 81462 + + ; you can't get into the Underforge anymore, either + TempUnderforgeAccess = false + PlayerHasBeastBlood = false + + ; Let everyone know you are no longer a werewolf + Game.GetPlayer().SendLycanthropyStateChanged(false) +EndFunction + + +Function Shutup(Actor toBeShut) + if (GenericDialogueSuppressor1.GetReference() == None) + GenericDialogueSuppressor1.ForceRefTo(toBeShut) + elseif (GenericDialogueSuppressor2.GetReference() == None) + GenericDialogueSuppressor2.ForceRefTo(toBeShut) + elseif (GenericDialogueSuppressor3.GetReference() == None) + GenericDialogueSuppressor3.ForceRefTo(toBeShut) + elseif (GenericDialogueSuppressor4.GetReference() == None) + GenericDialogueSuppressor4.ForceRefTo(toBeShut) + else +; Debug.Trace("C00: Can't shut anyone else up.") + endif +EndFunction + +Function UnShutup(Actor toBeUnShut) + if (GenericDialogueSuppressor1.GetReference() == toBeUnShut) + GenericDialogueSuppressor1.Clear() + elseif (GenericDialogueSuppressor2.GetReference() == toBeUnShut) + GenericDialogueSuppressor2.Clear() + elseif (GenericDialogueSuppressor3.GetReference() == toBeUnShut) + GenericDialogueSuppressor3.Clear() + elseif (GenericDialogueSuppressor4.GetReference() == toBeUnShut) + GenericDialogueSuppressor4.Clear() + else +; Debug.Trace("C00: " + toBeUnShut + " was never shut up.") + endif +EndFunction + +Function SwapFollowers() +; Debug.Trace("CSQ: Swapping followers.") + ; called when a story quest is assigning you a follower (C01, C03, C05, and C06) + ; so that you don't end up with too big of an entourage. + if (PlayerFollowerCount.GetValue() > 0) + FollowerScript.DismissFollower(2) + + ; Because the Dark Brotherhood does its own jimminess instead of + ; using the normal follower system, we have to dismiss manually. + if (DBScript.CiceroFollower == 1) + CiceroFollower.SetPlayerTeammate(false) + DBScript.CiceroFollower = 0 + DBScript.CiceroState = 1 + CiceroFollower.EvaluatePackage() + endif + + if (DBScript.Initiate1Follower == 1) + DBInitiateFollower1.SetPlayerTeammate(false) + DBScript.Initiate1Follower = 0 + DBScript.Initiate1State = 1 + DBInitiateFollower1.EvaluatePackage() + endif + + if (DBScript.Initiate2Follower == 1) + DBInitiateFollower2.SetPlayerTeammate(false) + DBScript.Initiate2Follower = 0 + DBScript.Initiate2State = 1 + DBInitiateFollower2.EvaluatePackage() + endif + endif + PlayerFollowerCount.SetValue(1) +EndFunction + +Function CleanupFollowerState() + PlayerFollowerCount.SetValue(0) +EndFunction diff --git a/source/scripts/companionsradiantquest.psc b/source/scripts/companionsradiantquest.psc new file mode 100644 index 00000000..c04613c6 --- /dev/null +++ b/source/scripts/companionsradiantquest.psc @@ -0,0 +1,82 @@ +Scriptname CompanionsRadiantQuest extends Quest Conditional + +Quest Property ParentQuest auto +ReferenceAlias Property Questgiver auto +ReferenceAlias Property MapMarker auto +bool Property IsRegistered = false auto +bool Property QuestgiverComesAlong = false auto conditional +bool Property IsActive = false auto conditional +bool Property IsAccepted = false auto conditional +bool Property WasRejected = false auto conditional +int Property RewardAmount = 100 auto +bool Property Succeeded = false auto +bool Property Premature = false auto + + +; called when quest is first setup, but before player has accepted it +Function Setup() + ; default properties are supposed to handle most of these, but just in case.... + ; IsRegistered = false + ; QuestgiverComesAlong = false + ; IsActive = false + ; IsAccepted = false + ; WasRejected = false + ; Succeeded = false + ; Premature = false + + int level = Game.GetPlayer().GetLevel() + if (level < 10) + RewardAmount = 100 + elseif (level < 20) + RewardAmount = 150 + elseif (level < 20) + RewardAmount = 200 + elseif (level < 20) + RewardAmount = 250 + else + RewardAmount = 300 + endif + + (ParentQuest as CompanionsHousekeepingScript).RegisterRadiantQuest(self) + SetStage(1) +EndFunction + +; called when player accepts quest +Function Accepted() +; Debug.Trace("CRQ: Accepting " + self + ".") + (ParentQuest as CompanionsHousekeepingScript).AcceptRadiantQuest(Questgiver.GetActorReference(), QuestgiverComesAlong) + if ( (MapMarker != None) && (MapMarker.GetReference() != None) ) + MapMarker.GetReference().AddToMap() + endif + IsAccepted = True + SetStage(10) +EndFunction + +; when player turns down the quest +Function Rejected() +; Debug.Trace("CRQ: Rejecting " + self + ".") + WasRejected = True +EndFunction + +; when player has finished quest, but not yet collected reward +Function Finished(bool _succeeded = true, bool _finished = true) +; Debug.Trace("CRQ: Finishing " + self + "; succeeded? " + _succeeded) + Succeeded = _succeeded + (ParentQuest as CompanionsHousekeepingScript).RadiantQuestFinished = _finished +EndFunction + +; when the quest is shutting down +Function Cleanup() + if (!Premature) + (ParentQuest as CompanionsHousekeepingScript).CompleteRadiantQuest(self) + endif +EndFunction + +; for when the player kills someone before they accepted the quest, etc +Function PrematureShutdown() +; Debug.Trace("CRQ: Shutting down " + self + "prematurely...") + IsAccepted = false + Premature = true + (ParentQuest as CompanionsHousekeepingScript).CycleRadiantQuests() + Cleanup() +EndFunction diff --git a/source/scripts/companionsstoryquest.psc b/source/scripts/companionsstoryquest.psc new file mode 100644 index 00000000..e6b432d6 --- /dev/null +++ b/source/scripts/companionsstoryquest.psc @@ -0,0 +1,43 @@ +Scriptname CompanionsStoryQuest extends Quest + +Quest Property CentralQuest auto +CompanionsStoryQuest Property PreviousQuest auto +CompanionsStoryQuest Property NextQuest auto + +; called when we're testing the quest and want to create its preconditions +; note that stage 1 will be set at the end of it +Function Setup() +; Debug.Trace("CSQ: Calling setup for " + self) + + CompanionsHousekeepingScript chs = (CentralQuest as CompanionsHousekeepingScript) + + if (PreviousQuest != None) + if (PreviousQuest.IsRunning() == false) + if (PreviousQuest.GetStageDone(1) == false) + PreviousQuest.SetStage(0) + endif +; Debug.Trace("CSQ: Setting stage 200 on " + PreviousQuest) + PreviousQuest.SetStage(200) + endif + endif + + ; Game.GetPlayer().AddToFaction(chs.CompanionsFaction) + if (!CentralQuest.GetStageDone(150)) + if (!CentralQuest.GetStageDone(100)) + CentralQuest.SetStage(100) + endif + CentralQuest.SetStage(150) + CentralQuest.CompleteQuest() + endif + chs.StartStoryQuest(self) ; sets stage 1 +EndFunction + +; called at stage 1 to do any real setup +Function Init() +; Debug.Trace("CSQ: Calling init for " + self) +EndFunction + +; called with stage 200 to do any necessary teardown (de-essentializing people, etc.) +Function Teardown() +; Debug.Trace("CSQ: Calling teardown for " + self) +EndFunction diff --git a/source/scripts/cr04questscript.psc b/source/scripts/cr04questscript.psc new file mode 100644 index 00000000..a8475fae --- /dev/null +++ b/source/scripts/cr04questscript.psc @@ -0,0 +1,23 @@ +Scriptname CR04QuestScript extends CompanionsRadiantQuest Conditional + +ReferenceAlias Property Brute auto +ReferenceAlias Property BruteActivated auto +ReferenceAlias Property FavorDialogueOpponent_Remote auto ; on DialogueFavorGeneric + +Function Accepted() + FavorDialogueOpponent_Remote.ForceRefTo(Brute.GetRef()) + BruteActivated.ForceRefTo(Brute.GetRef()) + parent.Accepted() +EndFunction + +Function CheckIntimidate(Actor opponent) +; Debug.Trace("CRQ CR04: Opponent: " + opponent + "; Brute: " + BruteActivated.GetReference()) + if (BruteActivated.GetReference() == opponent) + SetStage(20) + endif +EndFunction + +Function Cleanup() + FavorDialogueOpponent_Remote.Clear() + parent.Cleanup() +EndFunction diff --git a/source/scripts/craftingactivatelinker.psc b/source/scripts/craftingactivatelinker.psc new file mode 100644 index 00000000..327d503c --- /dev/null +++ b/source/scripts/craftingactivatelinker.psc @@ -0,0 +1,80 @@ +scriptName CraftingActivateLinker extends objectReference +; +;This script handles the Ore Veins and handshakes with the mining furniture +;=================================================================== + + +weapon Property RequiredWeapon01 Auto +{required for player to use - optional} + +Message Property FailureMessage Auto +{Message to say why you can't use this without RequiredWeapon} + +bool property requiresTool = false auto +{sets whether this requires a tool to operate + default = false} + +objectReference property objSelf auto hidden +{objectReference to self} + +AchievementsScript property AchievementsQuest auto + + +;=================================================================== +;;EVENT BLOCK +;=================================================================== + +event onLoad() + blockActivation() + objSelf = self as objectReference +endEvent + +event onActivate(objectReference akActivator) +; debug.Trace(self + " has been activated by " + akActivator) + + ;Actor is attempting to mine + if akActivator as actor + ;if the actor is the player + if akActivator == game.getPlayer() + ;if this is not depleted and the player has the right item + if requiresTool && playerHasTools() == false + FailureMessage.Show() + ;enter the furniture + else +; debug.Trace(self + " should cause " + akActivator + " to activate " + getLinkedRef()) + if getLinkedRef() + getLinkedRef().activate(akActivator) + AchievementsQuest.incHardworker(2) + Else +; debug.Trace(self + ": error this ore does not have a linkedRef") + endif + endif + Else + if getLinkedRef() + getLinkedRef().activate(akActivator) + Else +; debug.Trace(self + ": error this ore does not have a linkedRef") + endif + EndIf + + ;Something unexpected has activated the ore + Else +; debug.Trace(self + "has been activated by: " + akActivator + " why?") + endif +endEvent + +;;;May add on hit with pickaxe here later +; Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + +; endEvent + +;=================================================================== +;;FUNCTION BLOCK +;=================================================================== +bool function playerHasTools() + if Game.GetPlayer().GetItemCount(RequiredWeapon01) > 0 + return true + Else + return false + endIf +endFunction diff --git a/source/scripts/crimeguardsscript.psc b/source/scripts/crimeguardsscript.psc new file mode 100644 index 00000000..e4fc3013 --- /dev/null +++ b/source/scripts/crimeguardsscript.psc @@ -0,0 +1,119 @@ +ScriptName CrimeGuardsScript extends Quest + +ObjectReference Property CidhnaMineDoorA Auto +ObjectReference Property CidhnaMineDoorB Auto +ObjectReference Property CidhnaMineDoorLeverA Auto +ObjectReference Property CidhnaMineDoorLeverB Auto +Quest Property CidhnaMineJailEventScene Auto +GlobalVariable Property GameDaysPassed Auto +GlobalVariable Property pCrimeGuildDisc Auto +FavorDialogueScript Property FavorScript Auto +Faction Property pCrimeReach Auto +Faction Property pCrimeRift Auto +Faction Property pCrimeHaafingar Auto +Faction Property pCrimeEastmarch Auto +Faction Property pCrimeWhiterun Auto + +Function SetupCidhnaMine() + + If CidhnaMineJailEventScene.GetStageDone(10) == 0 +; debug.Trace("Running the Cidhna Mine intro scene") + CidhnaMineJailEventScene.SetStage(10) + EndIf + +EndFunction + +Function GuildDiscount(Actor pGuard) + + if pGuard.GetCrimeFaction() == pCrimeReach + pCrimeGuildDisc.Value = pCrimeReach.GetCrimeGold() / 2 + elseif pGuard.GetCrimeFaction() == pCrimeRift + pCrimeGuildDisc.Value = pCrimeRift.GetCrimeGold() / 2 + elseif pGuard.GetCrimeFaction() == pCrimeHaafingar + pCrimeGuildDisc.Value = pCrimeHaafingar.GetCrimeGold() / 2 + elseif pGuard.GetCrimeFaction() == pCrimeEastmarch + pCrimeGuildDisc.Value = pCrimeEastmarch.GetCrimeGold() / 2 + elseif pGuard.GetCrimeFaction() == pCrimeWhiterun + pCrimeGuildDisc.Value = pCrimeWhiterun.GetCrimeGold() / 2 + endif + +; Debug.Trace(self+"Guild gold check"+pCrimeGuildDisc.Value) + + UpdateCurrentInstanceGlobal(pCrimeGuildDisc) + +endFunction + +Function GuildPayoff(Actor pGuard) + + if pGuard.GetCrimeFaction() == pCrimeReach + guildModifyCrimeGold(pCrimeReach) + if Game.GetPlayer().IsTrespassing() == 0 + pCrimeReach.PlayerPayCrimeGold(false,false) + elseif Game.GetPlayer().IsTrespassing() == 1 + pCrimeReach.PlayerPayCrimeGold(false,true) + endif + elseif pGuard.GetCrimeFaction() == pCrimeRift + guildModifyCrimeGold(pCrimeRift) + if Game.GetPlayer().IsTrespassing() == 0 + pCrimeRift.PlayerPayCrimeGold(false,false) + elseif Game.GetPlayer().IsTrespassing() == 1 + pCrimeRift.PlayerPayCrimeGold(false,true) + endif + elseif pGuard.GetCrimeFaction() == pCrimeHaafingar + guildModifyCrimeGold(pCrimeHaafingar) + if Game.GetPlayer().IsTrespassing() == 0 + pCrimeHaafingar.PlayerPayCrimeGold(false,false) + elseif Game.GetPlayer().IsTrespassing() == 1 + pCrimeHaafingar.PlayerPayCrimeGold(false,true) + endif + elseif pGuard.GetCrimeFaction() == pCrimeEastmarch + guildModifyCrimeGold(pCrimeEastmarch) + if Game.GetPlayer().IsTrespassing() == 0 + pCrimeEastmarch.PlayerPayCrimeGold(false,false) + elseif Game.GetPlayer().IsTrespassing() == 1 + pCrimeEastmarch.PlayerPayCrimeGold(false,true) + endif + elseif pGuard.GetCrimeFaction() == pCrimeWhiterun + guildModifyCrimeGold(pCrimeWhiterun) + if Game.GetPlayer().IsTrespassing() == 0 + pCrimeWhiterun.PlayerPayCrimeGold(false,false) + elseif Game.GetPlayer().IsTrespassing() == 1 + pCrimeWhiterun.PlayerPayCrimeGold(false,true) + endif + endif + +endFunction + +function guildModifyCrimeGold(Faction CrimeFaction) + int crimeGoldViolent = CrimeFaction.GetCrimeGoldViolent() + int crimeGoldNonviolent = CrimeFaction.GetCrimeGoldNonviolent() + + CrimeFaction.ModCrimeGold(-crimeGoldNonviolent, abViolent = False) + CrimeFaction.ModCrimeGold(-crimeGoldViolent, abViolent = true) + + CrimeFaction.ModCrimeGold(pCrimeGuildDisc.GetValue() as int) + +endFunction + + +; call to set variable03 on guard when he decides to ignore petty crimegold +function SetLastArrestTime(Actor pGuard) + float nextTime = GameDaysPassed.GetValue() + 1.0 + pGuard.SetActorValue("Variable03", nextTime) +endfunction + + +; call this to bribe a guard to look the other way +function BribeGuard(Actor pGuard) + ; pay bribe + FavorScript.Bribe(pGuard) + ; stop alarms + Game.GetPlayer().StopCombatAlarm() +endFunction + +function PersuadeGuard(Actor pGuard) + ;use Persuade + FavorScript.ArrestPersuade(pGuard) + ; stop alarms + Game.GetPlayer().StopCombatAlarm() +endFunction \ No newline at end of file diff --git a/source/scripts/critterspawn01.psc b/source/scripts/critterspawn01.psc new file mode 100644 index 00000000..0b2b0616 --- /dev/null +++ b/source/scripts/critterspawn01.psc @@ -0,0 +1,2 @@ +scriptName critterSpawn01 extends critterSpawn +{Dummy script used for multiple critter types from one spawner} \ No newline at end of file diff --git a/source/scripts/curediseasescript.psc b/source/scripts/curediseasescript.psc new file mode 100644 index 00000000..2aa0d101 --- /dev/null +++ b/source/scripts/curediseasescript.psc @@ -0,0 +1,9 @@ +Scriptname CureDiseaseScript extends ActiveMagicEffect + +Message Property CureDiseaseMsg Auto + +Event OnEffectStart(Actor Target, Actor Caster) + + CureDiseaseMsg.Show() + +EndEvent \ No newline at end of file diff --git a/source/scripts/cwalliesscript.psc b/source/scripts/cwalliesscript.psc new file mode 100644 index 00000000..ff61026b --- /dev/null +++ b/source/scripts/cwalliesscript.psc @@ -0,0 +1,537 @@ +Scriptname CWAlliesScript extends Quest + +;This script handles adding new allies, and getting allies for use with sieges. + +;To add an ally to be available in future sieges: +;*Use function AddPotentialAlly() +;*Note: - there are optional parameters which allow this ally to show up at sieges in various holds. Make sure you set at least one of these paramters to true or you will never see the ally show up for any battles. + +;To get Allies to show up to sieges: +;1) Register markers for phase1/2/3/4/5 so allies have some place to go if the player isn't nearby call RegisterAllyPhaseMarkers() -- note this is MANDATORY +;2) Call ProcessAlliesForSiege() which finds appropriate allies, disables them, and then and moves them to Phase0Marker +;3) When it's appropriate stage in the siege quest, you then need to call EnableActiveAllies() which enables them causing them to appear at phase0marker. + +;After sieges, to get allies to go home: +;*Call DeactivateAllies() +;*!!! NOTE !!!! This assumes the allies have standard packages that take them home some place. If this is not true, I will need to revisit this system. + +CWScript Property CWs Auto + +ReferenceAlias Property Phase0Marker Auto +ReferenceAlias Property Phase1Marker Auto +ReferenceAlias Property Phase2Marker Auto +ReferenceAlias Property Phase3Marker Auto +ReferenceAlias Property Phase4Marker Auto +ReferenceAlias Property Phase5Marker Auto +ReferenceAlias Property Phase6Marker Auto + +ReferenceAlias Property PotentialAlly1 Auto +ReferenceAlias Property PotentialAlly2 Auto +ReferenceAlias Property PotentialAlly3 Auto +ReferenceAlias Property PotentialAlly4 Auto +ReferenceAlias Property PotentialAlly5 Auto +ReferenceAlias Property PotentialAlly6 Auto +ReferenceAlias Property PotentialAlly7 Auto +ReferenceAlias Property PotentialAlly8 Auto +ReferenceAlias Property PotentialAlly9 Auto +ReferenceAlias Property PotentialAlly10 Auto + +ReferenceAlias Property ActiveAlly1 Auto +ReferenceAlias Property ActiveAlly2 Auto +ReferenceAlias Property ActiveAlly3 Auto +ReferenceAlias Property ActiveAlly4 Auto +ReferenceAlias Property ActiveAlly5 Auto +ReferenceAlias Property ActiveAlly6 Auto +ReferenceAlias Property ActiveAlly7 Auto +ReferenceAlias Property ActiveAlly8 Auto +ReferenceAlias Property ActiveAlly9 Auto +ReferenceAlias Property ActiveAlly10 Auto + +Faction Property CWAlliesHaafingarFaction Auto +Faction Property CWAlliesReachFaction Auto +Faction Property CWAlliesHjaalmarchFaction Auto +Faction Property CWAlliesWhiterunFaction Auto +Faction Property CWAlliesFalkreathFaction Auto +Faction Property CWAlliesPaleFaction Auto +Faction Property CWAlliesWinterholdFaction Auto +Faction Property CWAlliesEastmarchFaction Auto +Faction Property CWAlliesRiftFaction Auto + +Faction Property CWAlliesImperialsOnlyFaction Auto +Faction Property CWAlliesSonsOnlyFaction Auto + + + +Location Property HaafingarHoldLocation Auto +Location Property ReachHoldLocation Auto +Location Property HjaalmarchHoldLocation Auto +Location Property WhiterunHoldLocation Auto +Location Property FalkreathHoldLocation Auto +Location Property PaleHoldLocation Auto +Location Property WinterholdHoldLocation Auto +Location Property EastmarchHoldLocation Auto +Location Property RiftHoldLocation Auto + +function MakeHadvarAndRalofPotentialAllies() + ;we're making them both potential allys when player joins either side, because IsAllowedtoJoinPlayersFaction() should prevent the wrong guy from showing up + +; CWScript.Log("CWAlliesScript", self + "MakeHadvarAndRalofPotentialAllies() calling AddPotentialAlly() for both Hadvar and Ralof") + + AddPotentialAlly( \ + CWs.HadvarRef, \ + AllowedInHaafingar = False, \ + AllowedInReach = True, \ + AllowedInHjaalmarch = True, \ + AllowedInWhiterun = True, \ + AllowedInFalkreath = True, \ + AllowedInPale = True, \ + AllowedInWinterhold = True, \ + AllowedInEastmarch = False, \ + AllowedInRift = True, \ + ImperialsOnly = True, \ + SonsOnly = false \ + ) + + + AddPotentialAlly( \ + CWs.RalofRef, \ + AllowedInHaafingar = False, \ + AllowedInReach = True, \ + AllowedInHjaalmarch = True, \ + AllowedInWhiterun = True, \ + AllowedInFalkreath = True, \ + AllowedInPale = True, \ + AllowedInWinterhold = True, \ + AllowedInEastmarch = False, \ + AllowedInRift = True, \ + ImperialsOnly = False, \ + SonsOnly = True \ + ) + +EndFunction + +function AddPotentialAlly( \ +ObjectReference ReferenceToAdd, \ +Bool AllowedInHaafingar = false, \ +Bool AllowedInReach = false, \ +Bool AllowedInHjaalmarch = false, \ +Bool AllowedInWhiterun = false, \ +Bool AllowedInFalkreath = false, \ +Bool AllowedInPale = false, \ +Bool AllowedInWinterhold = false, \ +Bool AllowedInEastmarch = false, \ +Bool AllowedInRift = false, \ +bool ImperialsOnly = false, \ +bool SonsOnly = false \ +) + +; CWScript.Log("CWAlliesScript", self + "AddPotentialAlly() trying to add " + ReferenceToAdd + "Calling GetFreePotenialAllyAlias()") + + ReferenceAlias AliasToForceInto = GetFreePotentialAllyAlias() + + Actor ActorToAdd = ReferenceToAdd as Actor + + if AliasToForceInto != None +; CWScript.Log("CWAlliesScript", self + "AddPotentialAlly() forcing " + ReferenceToAdd + " into alias " + AliasToForceInto) + AliasToForceInto.ForceRefTo(ReferenceToAdd) + + if AllowedInHaafingar +; CWScript.Log("CWAlliesScript", self + "adding " + ReferenceToAdd + " to faction " + CWAlliesHaafingarFaction) + ActorToAdd.AddToFaction(CWAlliesHaafingarFaction) + EndIf + + if AllowedInReach +; CWScript.Log("CWAlliesScript", self + "adding " + ReferenceToAdd + " to faction " + CWAlliesReachFaction) + ActorToAdd.AddToFaction(CWAlliesReachFaction) + EndIf + + if AllowedInHjaalmarch +; CWScript.Log("CWAlliesScript", self + "adding " + ReferenceToAdd + " to faction " + CWAlliesHjaalmarchFaction) + ActorToAdd.AddToFaction(CWAlliesHjaalmarchFaction) + EndIf + + if AllowedInWhiterun +; CWScript.Log("CWAlliesScript", self + "adding " + ReferenceToAdd + " to faction " + CWAlliesWhiterunFaction) + ActorToAdd.AddToFaction(CWAlliesWhiterunFaction) + EndIf + + if AllowedInFalkreath +; CWScript.Log("CWAlliesScript", self + "adding " + ReferenceToAdd + " to faction " + CWAlliesFalkreathFaction) + ActorToAdd.AddToFaction(CWAlliesFalkreathFaction) + EndIf + + if AllowedInPale +; CWScript.Log("CWAlliesScript", self + "adding " + ReferenceToAdd + " to faction " + CWAlliesPaleFaction) + ActorToAdd.AddToFaction(CWAlliesPaleFaction) + EndIf + + if AllowedInWinterhold +; CWScript.Log("CWAlliesScript", self + "adding " + ReferenceToAdd + " to faction " + CWAlliesWinterholdFaction) + ActorToAdd.AddToFaction(CWAlliesWinterholdFaction) + EndIf + + if AllowedInEastmarch +; CWScript.Log("CWAlliesScript", self + "adding " + ReferenceToAdd + " to faction " + CWAlliesEastmarchFaction) + ActorToAdd.AddToFaction(CWAlliesEastmarchFaction) + EndIf + + if AllowedInRift +; CWScript.Log("CWAlliesScript", self + "adding " + ReferenceToAdd + " to faction " + CWAlliesRiftFaction) + ActorToAdd.AddToFaction(CWAlliesRiftFaction) + EndIf + + if ImperialsOnly +; CWScript.Log("CWAlliesScript", self + "adding " + ReferenceToAdd + " to faction " + CWAlliesImperialsOnlyFaction) + ActorToAdd.AddToFaction(CWAlliesImperialsOnlyFaction) + EndIf + + if SonsOnly +; CWScript.Log("CWAlliesScript", self + "adding " + ReferenceToAdd + " to faction " + CWAlliesSonsOnlyFaction) + ActorToAdd.AddToFaction(CWAlliesSonsOnlyFaction) + EndIf + + Else + ;WARNING WE COULDN'T FIND FREE SLOT!!!! +; CWScript.Log("CWAlliesScript", self + " WARNING: AddPotentialAlly() couldn't find a free slot for the ally.", 2, 1, 1 ) + + EndIf + +EndFunction + + + +ReferenceAlias function GetFreePotentialAllyAlias() + ReferenceAlias AliasToReturn + + if PotentialAlly1.GetReference() == False + AliasToReturn = PotentialAlly1 + + ElseIf PotentialAlly2.GetReference() == False + AliasToReturn = PotentialAlly2 + + ElseIf PotentialAlly3.GetReference() == False + AliasToReturn = PotentialAlly3 + + ElseIf PotentialAlly4.GetReference() == False + AliasToReturn = PotentialAlly4 + + ElseIf PotentialAlly5.GetReference() == False + AliasToReturn = PotentialAlly5 + + ElseIf PotentialAlly6.GetReference() == False + AliasToReturn = PotentialAlly6 + + ElseIf PotentialAlly7.GetReference() == False + AliasToReturn = PotentialAlly7 + + ElseIf PotentialAlly8.GetReference() == False + AliasToReturn = PotentialAlly8 + + ElseIf PotentialAlly9.GetReference() == False + AliasToReturn = PotentialAlly9 + + ElseIf PotentialAlly10.GetReference() == False + AliasToReturn = PotentialAlly10 + + Else + ;RAN OUT OF SLOTS +; CWScript.Log("CWAlliesScript", self + " WARNING: GetFreePotenialAllyAlias() ran out of PotentialAlly Aliases, returning none.", 2, 1, 1 ) + return None + + EndIf + +; CWScript.Log("CWAlliesScript", self + "GetFreePotenialAllyAlias() returning " + AliasToReturn) + + return AliasToReturn + +EndFunction + + + +function RegisterAllyPhaseMarkers(ObjectReference Phase0MarkerRef, ObjectReference Phase1MarkerRef, ObjectReference Phase2MarkerRef, ObjectReference Phase3MarkerRef, ObjectReference Phase4MarkerRef, ObjectReference Phase5MarkerRef, ObjectReference Phase6MarkerRef) +{Called by Siege scripts to register 1 set of phase1/2/3/4/5 markers for all the allies to use for that siege} + +; CWScript.Log("CWAlliesScript", self + "RegisterAllyPhaseMarkers() forcing Refs: " + Phase0MarkerRef + "," + Phase1MarkerRef + ", " + Phase2MarkerRef + ", " + Phase3MarkerRef + ", " + Phase4MarkerRef + ", " + Phase5MarkerRef + ", " + Phase6MarkerRef + " into Phase0/1/2/3/4/5/6Marker Aliases.") + Phase0Marker.ForceRefTo(Phase0MarkerRef) + Phase1Marker.ForceRefTo(Phase1MarkerRef) + Phase2Marker.ForceRefTo(Phase2MarkerRef) + Phase3Marker.ForceRefTo(Phase3MarkerRef) + Phase4Marker.ForceRefTo(Phase4MarkerRef) + Phase5Marker.ForceRefTo(Phase5MarkerRef) + Phase6Marker.ForceRefTo(Phase6MarkerRef) + +EndFunction + +function ProcessAlliesForSiege(Location HoldLocation) +{Called by Siege scripts to find appropriate allies and move them to Phase0Marker} +; CWScript.Log("CWAlliesScript", self + "ProcessAlliesForSiege() for location " + HoldLocation + " will now try to find appropriate allies, move them to Phase1Marker and disable them.") + + ObjectReference Phase0MarkerRef = Phase0Marker.GetReference() + + if Phase0MarkerRef == None +; CWScript.Log("CWAlliesScript", self + " WARNING: ProcessAlliesForSiege() couldn't find a reference in Phase0Marker. Make sure Siege Script calls RegisterAllyPhaseMarkers() before calling ProcessAlliesForSiege()!!! ", 2, 1, 1 ) + Return + EndIf + + TryToProcessAlly(PotentialAlly1, HoldLocation, Phase0MarkerRef) + TryToProcessAlly(PotentialAlly2, HoldLocation, Phase0MarkerRef) + TryToProcessAlly(PotentialAlly3, HoldLocation, Phase0MarkerRef) + TryToProcessAlly(PotentialAlly4, HoldLocation, Phase0MarkerRef) + TryToProcessAlly(PotentialAlly5, HoldLocation, Phase0MarkerRef) + TryToProcessAlly(PotentialAlly6, HoldLocation, Phase0MarkerRef) + TryToProcessAlly(PotentialAlly7, HoldLocation, Phase0MarkerRef) + TryToProcessAlly(PotentialAlly8, HoldLocation, Phase0MarkerRef) + TryToProcessAlly(PotentialAlly9, HoldLocation, Phase0MarkerRef) + TryToProcessAlly(PotentialAlly10, HoldLocation, Phase0MarkerRef) + +; CWScript.Log("CWAlliesScript", self + "ProcessAlliesForSiege() done processing potential allies.") + +EndFunction + +Function TryToProcessAlly(ReferenceAlias PotentialAlly, Location HoldLocation, ObjectReference Phase0MarkerRef) +; CWScript.Log("CWAlliesScript", self + "TryToProcessAlly() for PotentialAlly Alias:" + PotentialAlly + " for HoldLocation:" + HoldLocation) + + actor CurrentPotentialAlly = TryPromoteToActiveAllyAndReturnActor(PotentialAlly, HoldLocation) + + if CurrentPotentialAlly +; CWScript.Log("CWAlliesScript", self + "TryToProcessAlly() disabling " + CurrentPotentialAlly + " and moving to to " + Phase0MarkerRef + "." ) + CurrentPotentialAlly.Disable() + CurrentPotentialAlly.MoveTo(Phase0MarkerRef) + + Else ;for some reason TryPromoteToActiveAllyAndReturnActor failed to return an actor. This does not mean something broke. There are cases where this is fine (for instance tha actor isn't in the faction that allows him to show up in the hold +; CWScript.Log("CWAlliesScript", self + "TryToProcessAlly() did not get an actor from TryPromoteToActiveAllyAndReturnActor( " + PotentialAlly + " ) so we are ignoring it.") + + EndIf + +EndFunction + +Actor function TryPromoteToActiveAllyAndReturnActor(ReferenceAlias PotentialAllyToPromote, Location HoldLocation) + + Actor ActorToForce = PotentialAllyToPromote.GetActorReference() + ReferenceAlias AliasToForceInto = GetFreeActiveAllyAlias() + + ;check that there is an Actor in PotentialAllyToPromote + if ActorToForce == None +; CWScript.Log("CWAlliesScript", self + " TryPromoteToActiveAllyAndReturnActor() did not find an actor in PotentialAllyToPromote alias: " + PotentialAllyToPromote) + ActorToForce = None ;it's already none, but for consistency and readability I'm setting it here. + + Else + ;Check that Actor is in the correct faction (ie that he is allowed to show up in the HoldLocation) + if IsAllowedInLocation(ActorToForce, HoldLocation) && IsAllowedToJoinPlayersFaction(ActorToForce) + ;Is Allowed in location +; CWScript.Log("CWAlliesScript", self + "TryPromoteToActiveAllyAndReturnActor() found actor" + ActorToForce + " is indeed allowed in location and is allowed to join up with the player's faction." ) + + if AliasToForceInto != None +; CWScript.Log("CWAlliesScript", self + "TryPromoteToActiveAllyAndReturnActor() forcing " + ActorToForce + " into alias " + AliasToForceInto) + AliasToForceInto.ForceRefTo(ActorToForce) + + Else + ;WARNING WE COULDN'T FIND FREE SLOT!!!! +; CWScript.Log("CWAlliesScript", self + " WARNING: TryPromoteToActiveAllyAndReturnActor() couldn't find a free slot for the ally.", 2, 1, 1 ) + ActorToForce = None + + EndIf + + Else ; Is Not Allowed in Location +; CWScript.Log("CWAlliesScript", self + "promoteToActiveAlly() found actor" + ActorToForce + " is not allowed in location(" + HoldLocation + ") OR is not allowed to join player's faction:" + CWs.PlayerAllegiance + "[" + CWs.FactionName(CWs.PlayerAllegiance) +"]") + ActorToForce = None + EndIf + + + Endif + +; CWScript.Log("CWAlliesScript", self + "promoteToActiveAlly() returning " + ActorToForce) + return ActorToForce + +EndFunction + + +bool function IsAllowedInLocation(Actor ActorToCheck, Location HoldLocationToCheck) + + Bool IsAllowed + + if HoldLocationToCheck == HaafingarHoldLocation + if ActorToCheck.IsInFaction(CWAlliesHaafingarFaction) + IsAllowed = True + Else +; CWScript.Log("CWAlliesScript", self + "IsAllowedInLocation() did not find ActorToCheck" + ActorToCheck + " in CWAlliesHaafingarFaction. Will return false.") + IsAllowed = False + EndIf + + elseif HoldLocationToCheck == ReachHoldLocation + if ActorToCheck.IsInFaction(CWAlliesReachFaction) + IsAllowed = true + else +; CWScript.Log("CWAlliesScript", self + "IsAllowedInLocation() did not find ActorToCheck" + ActorToCheck + " in CWAlliesReachFaction. Will return false.") + IsAllowed = False + Endif + + elseif HoldLocationToCheck == HjaalmarchHoldLocation + if ActorToCheck.IsInFaction(CWAlliesHjaalmarchFaction) + IsAllowed = true + else +; CWScript.Log("CWAlliesScript", self + "IsAllowedInLocation() did not find ActorToCheck" + ActorToCheck + " in CWAlliesHjaalmarchFaction. Will return false.") + IsAllowed = False + Endif + + elseif HoldLocationToCheck == WhiterunHoldLocation + if ActorToCheck.IsInFaction(CWAlliesWhiterunFaction) + IsAllowed = true + else +; CWScript.Log("CWAlliesScript", self + "IsAllowedInLocation() did not find ActorToCheck" + ActorToCheck + " in CWAlliesWhiterunFaction. Will return false.") + IsAllowed = False + Endif + + elseif HoldLocationToCheck == FalkreathHoldLocation + if ActorToCheck.IsInFaction(CWAlliesFalkreathFaction) + IsAllowed = true + else +; CWScript.Log("CWAlliesScript", self + "IsAllowedInLocation() did not find ActorToCheck" + ActorToCheck + " in CWAlliesFalkreathFaction. Will return false.") + IsAllowed = False + Endif + + elseif HoldLocationToCheck == PaleHoldLocation + if ActorToCheck.IsInFaction(CWAlliesPaleFaction) + IsAllowed = true + else +; CWScript.Log("CWAlliesScript", self + "IsAllowedInLocation() did not find ActorToCheck" + ActorToCheck + " in CWAlliesPaleFaction. Will return false.") + IsAllowed = False + Endif + + elseif HoldLocationToCheck == WinterholdHoldLocation + if ActorToCheck.IsInFaction(CWAlliesWinterholdFaction) + IsAllowed = true + else +; CWScript.Log("CWAlliesScript", self + "IsAllowedInLocation() did not find ActorToCheck" + ActorToCheck + " in CWAlliesWinterholdFaction. Will return false.") + IsAllowed = False + Endif + + elseif HoldLocationToCheck == EastmarchHoldLocation + if ActorToCheck.IsInFaction(CWAlliesEastmarchFaction) + IsAllowed = true + else +; CWScript.Log("CWAlliesScript", self + "IsAllowedInLocation() did not find ActorToCheck" + ActorToCheck + " in CWAlliesEastmarchFaction. Will return false.") + IsAllowed = False + Endif + + elseif HoldLocationToCheck == RiftHoldLocation + if ActorToCheck.IsInFaction(CWAlliesRiftFaction) + IsAllowed = true + else +; CWScript.Log("CWAlliesScript", self + "IsAllowedInLocation() did not find ActorToCheck" + ActorToCheck + " in CWAlliesRiftFaction. Will return false.") + IsAllowed = False + Endif + + Else +; CWScript.Log("CWAlliesScript", self + " WARNING: IsAllowedInLocation() found an unexpected location for HoldLocationToCheck:" + HoldLocationToCheck, 2, 1, 1 ) + IsAllowed = False + EndIf + + return IsAllowed + +EndFunction + +bool Function IsAllowedToJoinPlayersFaction(Actor ActorToCheck) + + bool returnVal + + if CWs.PlayerAllegiance == CWs.iImperials && ActorToCheck.IsInFaction(CWAlliesSonsOnlyFaction) + +; CWScript.Log("CWAlliesScript", self + "IsAllowedToJoinPlayersFaction(" + ActorToCheck + ") is in CWAlliesSonsOnlyFaction and player Imperial. Will return false.") + + returnVal = False + + elseif CWs.PlayerAllegiance == CWs.iSons && ActorToCheck.IsInFaction(CWAlliesImperialsOnlyFaction) +; CWScript.Log("CWAlliesScript", self + "IsAllowedToJoinPlayersFaction(" + ActorToCheck + ") is in CWAlliesImperialsOnlyFaction and player Sons. Will return false.") + returnVal = False + + Else + returnVal = True + + EndIf + + return returnVal + +EndFunction + + +ReferenceAlias function GetFreeActiveAllyAlias() + ReferenceAlias AliasToReturn + + if ActiveAlly1.GetReference() == False + AliasToReturn = ActiveAlly1 + + ElseIf ActiveAlly2.GetReference() == False + AliasToReturn = ActiveAlly2 + + ElseIf ActiveAlly3.GetReference() == False + AliasToReturn = ActiveAlly3 + + ElseIf ActiveAlly4.GetReference() == False + AliasToReturn = ActiveAlly4 + + ElseIf ActiveAlly5.GetReference() == False + AliasToReturn = ActiveAlly5 + + ElseIf ActiveAlly6.GetReference() == False + AliasToReturn = ActiveAlly6 + + ElseIf ActiveAlly7.GetReference() == False + AliasToReturn = ActiveAlly7 + + ElseIf ActiveAlly8.GetReference() == False + AliasToReturn = ActiveAlly8 + + ElseIf ActiveAlly9.GetReference() == False + AliasToReturn = ActiveAlly9 + + ElseIf ActiveAlly10.GetReference() == False + AliasToReturn = ActiveAlly10 + + Else + ;RAN OUT OF SLOTS +; CWScript.Log("CWAlliesScript", self + " WARNING: GetFreePotenialAllyAlias() ran out of ActiveAlly Aliases, returning none.", 2, 1, 1 ) + return None + + EndIf + +; CWScript.Log("CWAlliesScript", self + "GetFreePotenialAllyAlias() returning " + AliasToReturn) + + return AliasToReturn + +EndFunction + +function EnableActiveAllies() +; CWScript.Log("CWAlliesScript", self + "EnableActiveAllies() calling TryToEnable() on all of the ActiveAllyX aliases.") + ActiveAlly1.TryToEnable() + ActiveAlly2.TryToEnable() + ActiveAlly3.TryToEnable() + ActiveAlly4.TryToEnable() + ActiveAlly5.TryToEnable() + ActiveAlly6.TryToEnable() + ActiveAlly7.TryToEnable() + ActiveAlly8.TryToEnable() + ActiveAlly9.TryToEnable() + ActiveAlly10.TryToEnable() + +; CWScript.Log("CWAlliesScript", self + "EnableActiveAllies() finished trying to enable all the active allies.") +EndFunction + +function DeactivateAllies() +{Called by Siege script when the siege is over and the allies should go home. This assumes the Allies have packages that take them some place. If this is not true, I need to revisit this system.} + +; CWScript.Log("CWAlliesScript", self + "EnableActiveAllies() calling Clear() on all of the ActiveAllyX aliases.") + + ActiveAlly1.Clear() + ActiveAlly2.Clear() + ActiveAlly3.Clear() + ActiveAlly4.Clear() + ActiveAlly5.Clear() + ActiveAlly6.Clear() + ActiveAlly7.Clear() + ActiveAlly8.Clear() + ActiveAlly9.Clear() + ActiveAlly10.Clear() + +EndFunction + diff --git a/source/scripts/cwcampaignpollformissionacceptscript.psc b/source/scripts/cwcampaignpollformissionacceptscript.psc new file mode 100644 index 00000000..933d323b --- /dev/null +++ b/source/scripts/cwcampaignpollformissionacceptscript.psc @@ -0,0 +1,61 @@ +Scriptname CWCampaignPollForMissionAcceptScript extends Quest + + +;## Quests ## +Quest Property CW Auto +Quest Property CWCampaign Auto + +;## Scripts ## +;These will be assigned in the OnInit() block +CWScript Property CWs Auto hidden +CWCampaignScript Property CWCampaignS Auto hidden + + +Event OnInit() + +; CWScript.Log("CWCampaignPollForMissionAcceptScript" , " OnInit()", 0, True, True) + + CWs = CW as CWScript + CWCampaignS = CWCampaign as CWCampaignScript + + registerForUpdate(5) +EndEvent + +auto State NotPolling + Event OnUpdate() +; CWScript.Log("CWCampaignPollForMissionAcceptScript" , " State: 'NotPolling' OnUpdate(), doing nothing." ) + EndEvent + +EndState + +State Polling + Event OnUpdate() +; CWScript.Log("CWCampaignPollForMissionAcceptScript" , " State: 'Polling' OnUpdate(), polling for quest acceptance or GameDaysPassed > NextPhaseDay." ) + + if CWCampaignS.AcceptedMission > 0 +; CWScript.Log("CWCampaignPollForMissionAcceptScript" , " State: 'Polling' See's AcceptedMission > 0, going to State 'NotPolling'" ) + StopPolling() + + Elseif CWs.GameDaysPassed.value > CWCampaignS.NextPhaseDay +; CWScript.Log("CWCampaignPollForMissionAcceptScript" , " State: 'Polling' sees that GameDaysPassed(" + CWs.GameDaysPassed.value + ") > NextPhaseDay(" + CWCampaignS.NextPhaseDay + "), stopping polling, and calling AdvanceCampaignPhase()" ) + StopPolling() + CWCampaignS.AdvanceCampaignPhase() ;this will among other things set AcceptedMission to 0 + + Else +; CWScript.Log("CWCampaignPollForMissionAcceptScript" , " State: 'Polling' sees that GameDaysPassed(" + CWs.GameDaysPassed.value + ") < NextPhaseDay(" + CWCampaignS.NextPhaseDay + "), will keep polling." ) + + EndIf + + EndEvent + +EndState + + +Function StartPolling() + GoToState("Polling") +EndFunction + +Function StopPolling() + GoToState("NotPolling") +EndFunction + diff --git a/source/scripts/cwcampaignscript.psc b/source/scripts/cwcampaignscript.psc new file mode 100644 index 00000000..a0bef51e --- /dev/null +++ b/source/scripts/cwcampaignscript.psc @@ -0,0 +1,1627 @@ +Scriptname CWCampaignScript extends Quest Conditional + +;#POINTER TO GLOBAL SHOW DEBUG TRACES +GlobalVariable property debugOn auto conditional ;0 = unset, 1 = set - show warnings +{Pointer to Global CWDebugOn, used to toggle campaign start message} + + +int property initCampaign auto conditional hidden ;0 = unset, 1 = running through initialization quest stages, -1 = finished + +int property costPatrol auto conditional hidden +int property ownerPatrol1 auto conditional hidden +int property ownerPatrol2 auto conditional hidden +int property ownerPatrol3 auto conditional hidden +int property ownerPatrol4 auto conditional hidden +int property ownerPatrol5 auto conditional hidden + +;What type each each offered mission? Used to flavor initial dialog when Field Officer is offering player missions +int property Mission1Type auto conditional hidden +int property Mission2Type auto conditional hidden +int property Mission3Type auto conditional hidden +;0 = un/reset +;100 = Tutorial / Ambush +;1 = attack settlement +;2 = sabotage resource +;3 = intercept courier +;4 = rescue soldier from fort prison +;5 = assassinate enemy field co +;6 = turn coats +;7 = blackmail steward +;8 - recruit a giant +;9 = steal plans +;10 - recruit a warrior ally +;11 - recruit orc ally +;200 - Fort Siege + +;N = TBD + + +;*** Below is for debugging what is changing the properties in script -- note, this will break conditions functions, but I'm leaving it here for future reference. +;int __Mission1Type +;int property Mission1Type +; int function get() +; return __Mission1Type +; endFunction +; function set(int value) +; ; debug.tracestack("CWCampaignScript Mission1Type being set to: " + value) +; __Mission1Type = value +; endFunction +;endProperty + +;int __Mission2Type +;int property Mission2Type +; int function get() +; return __Mission2Type +; endFunction +; function set(int value) +; ; debug.tracestack("CWCampaignScript Mission2Type being set to: " + value) +; __Mission2Type = value +; endFunction +;endProperty + + + +int Property ResolutionMissionType Auto Conditional Hidden +;1 = Attack Minor Hold Capital +;2 = Defend Minor Hold Capital +;3 = Attack Major Hold Capital +;4 = Defend Major Hold Capital + +int property acceptedHooks auto conditional hidden ;0 = un/reset, 1 = player has heard the opening mission hooks (unlocks mission topics) +int property acceptedMission auto conditional hidden ;0 = un/reset, 1 = player has accepted a mission (suppresses other mission topics) + +int Property acceptedTutorialHooks Auto Conditional Hidden ;0 = un/reset, 1 = player has heard the opening mission hooks (unlocks mission topics) + + +int property resolutionPhase auto conditional hidden ; N = at what CWCampaignPhase are we considered to be in the "resolution" phase, meaning the final mission (which can also resolve offscreen if player is absent) + ;Reminder: GLOBAL CWCampaignPhase is the current phase + +int property resolveOffscreen auto conditional hidden ;0 = un/reset, 1 = waiting for CW to resolve offscreen and set this quest's stage 255 to stop it + +int Property currentAttackDelta auto Conditional Hidden + +int attackDeltaMissionBonus ; this variable holds bonus attack delta points earned by completing certain CWMission quests -- see Add/SetAttackDeltaMissionBonus() + +;"timer" variables +float property acceptDays auto conditional hidden ;(set in stage 1) How many days we allow the player to accept a mission before advancing the phase without him +float property nextPhaseDay auto conditional hidden ;At start of each phase, GameDaysPassed + acceptDays, after which we advance the phase +float property missionDays auto conditional hidden ;(set in stage 1) How many days we allow the player to complete an accepted mission before we consider it a failure +int property failedMission auto conditional hidden ;0 = unset, -N = player got dialog about failing mission, N = player just failed a mission of the numeric Mission type and should get dialogue about it (see comment under property "Mission1Type" above +int property completedMission auto conditional hidden ;0 = unset, -N player got dialog about completing mission, N = player just completed a mission of the numeric Mission type and should get dialgoue about it (see comment under property "Mission1Type" above + + + + +int Property MissionAcceptancePollWait auto Hidden ;How long to wait between ticks to poll for MissionAcceptance (see PollForMissionAcceptance()) + +int Property AttackDeltaBonusForKillingCapitalGarrison auto hidden ;how many points to add to the AttackDelta if the player killed all the guards in the capital location +Float Property AttackDeltaGarrisonValueModifierForDestroyingResource auto Hidden ;A multiplier to a garrison's cost when turning that garrison into a CurrentAttackDelta points... when the player destroys a resource, the garrison should contribute less to the attack delta. This is the multiplier that reflects that. Set in OnInit() + + +;## Quests ## +Quest Property CW Auto +{Pointer to CW Quest} + +Quest Property CWMission00 Auto + +Quest Property CWSiege Auto +{Pointer to CWSiegeScript on CWSiege} + +;## Aliases ## +;Pointers to CWCampaign Aliases: + +ReferenceAlias Property CampaignStartMarker auto + +ReferenceAlias property Rikke Auto +ReferenceAlias property Galmar Auto + +ReferenceAlias property GenericFieldCOImperial Auto +ReferenceAlias property GenericFieldCOSons Auto + +ReferenceAlias property FieldCO Auto ;Actual field officer for player's faction (Rikke, or Galmar) +ReferenceAlias property EnemyFieldCO Auto ;Actual field officer for player's enemy (Generic Field Commander Imperial / Sons) + +LocationAlias Property Hold Auto + + +LocationAlias Property Garrison1 Auto +LocationAlias Property Garrison2 Auto +LocationAlias Property Garrison3 Auto +LocationAlias Property Garrison4 Auto + +ReferenceAlias Property Garrison1ResourceObject Auto +ReferenceAlias Property Garrison2ResourceObject Auto +ReferenceAlias Property Garrison3ResourceObject Auto +ReferenceAlias Property Garrison4ResourceObject Auto + +LocationAlias Property Fort Auto + +LocationAlias Property GarrisonDefenderOnly1 Auto +LocationAlias Property GarrisonDefenderOnly2 Auto +LocationAlias Property GarrisonDefenderOnly3 Auto +LocationAlias Property GarrisonDefenderOnly4 Auto +LocationAlias Property GarrisonDefenderOnly5 Auto +LocationAlias Property GarrisonDefenderOnly6 Auto + +ReferenceAlias Property GarrisonDefenderOnly1ResourceObject Auto +ReferenceAlias Property GarrisonDefenderOnly2ResourceObject Auto +ReferenceAlias Property GarrisonDefenderOnly3ResourceObject Auto +ReferenceAlias Property GarrisonDefenderOnly4ResourceObject Auto + + +LocationAlias Property Capital Auto +LocationAlias Property CapitalHQ Auto + +LocationAlias Property CampImperial Auto +LocationAlias Property CampSons Auto + +LocationAlias Property FieldHQ Auto +LocationAlias Property EnemyFieldHQ Auto + +ReferenceAlias Property CampEnableImperial Auto +ReferenceAlias Property CampEnableSons Auto + +ReferenceAlias Property CampImperialLocationCenterMarker Auto +ReferenceAlias Property CampSonsLocationCenterMarker Auto +ReferenceAlias Property CapitalHQMarker Auto + + +LocationAlias Property Patrols Auto + +ReferenceAlias Property PatrolsDefaultEnableImperial Auto +ReferenceAlias Property PatrolsDefaultEnableSons Auto + + +ReferenceAlias Property PatrolsEnableImperial1 Auto +ReferenceAlias Property PatrolsEnableImperial2 Auto +ReferenceAlias Property PatrolsEnableImperial3 Auto +ReferenceAlias Property PatrolsEnableImperial4 Auto +ReferenceAlias Property PatrolsEnableImperial5 Auto + + +ReferenceAlias Property PatrolsEnableSons1 Auto +ReferenceAlias Property PatrolsEnableSons2 Auto +ReferenceAlias Property PatrolsEnableSons3 Auto +ReferenceAlias Property PatrolsEnableSons4 Auto +ReferenceAlias Property PatrolsEnableSons5 Auto + +;# EXTERNAL aliases: +;CWCampaignObj Aliases: +ReferenceAlias Property CWCampaignObjFieldCO Auto +ReferenceAlias Property CWCampaignObjFactionLeader Auto +ReferenceAlias Property CWCampaignObjCampaignStartMarker Auto +LocationAlias Property CWCampaignObjCampaignHold Auto + + +;## Globals ## +GlobalVariable Property GameDaysPassed Auto +GlobalVariable Property CWCampaignPhase Auto +GlobalVariable Property ResourceDestroyedAtStage Auto +GlobalVariable Property CWDebugSkipPurchase Auto ;if == 1, skips purchaing garrisons + +;## Keywords ## +Keyword Property CWOwner Auto +Keyword Property CWCost Auto +Keyword Property CWPurchasedByAttacker Auto + +Keyword Property CWMissionStart Auto +Keyword Property CWResolution01Start Auto ;attack settlement capital resolution mission +Keyword Property CWResolution02Start Auto ;defend settlement capital resolution mission +Keyword Property CWMissionTutorialStart Auto +Keyword Property CWSiegeStart Auto ;used to start siege attack and defend quests for cities + + +Keyword Property LocTypeCity Auto +Keyword Property LocTypeHabitation Auto + +;## Location Ref Types ## +LocationRefType Property CWSoldier Auto +LocationRefType Property CWPatrolDefault Auto +LocationRefType Property CWPatrol1 Auto +LocationRefType Property CWPatrol2 Auto +LocationRefType Property CWPatrol3 Auto +LocationRefType Property CWPatrol4 Auto +LocationRefType Property CWPatrol5 Auto + + + +;## Object References ## +ObjectReference Property CWMission1Ref Auto ;Passed in to SendStoryEvent when generating mission quests as a way to identify which mission # +ObjectReference Property CWMission2Ref Auto ;Passed in to SendStoryEvent when generating mission quests as a way to identify which mission # +ObjectReference Property CWMission3Ref Auto ;Passed in to SendStoryEvent when generating mission quests as a way to identify which mission # + +;## Activators ## + +;*** !! *** !! *** !! these are now just forms, and will be set with Game.GetForm(HEX ID) function rather than being pointed at in the editor. As soon as we get Activator objects in Papyrus, this need to change to point directly at the activators +Form Property ResourceObjectFarm auto ;*** !!! TEMPORARILY SET IN OnInit() event using GetForm().... REMOVE THAT FROM THE OnInit() event +Form Property ResourceObjectMill auto ;*** !!! TEMPORARILY SET IN OnInit() event using GetForm().... REMOVE THAT FROM THE OnInit() event +Form Property ResourceObjectMine auto ;*** !!! TEMPORARILY SET IN OnInit() event using GetForm().... REMOVE THAT FROM THE OnInit() event + + +;## Scripts ## +;These will be assigned in the OnInit() block +CWScript Property CWs Auto hidden + + +;# SetOwner() Location Variables -- these should be arrays, consider converting when we get arrays implemented in the language +;Variables for holding locations that are purchased so we can pass them all to CWScript SetOwner() +Location PurchasedLocationImperial1 +Location PurchasedLocationImperial2 +Location PurchasedLocationImperial3 +Location PurchasedLocationImperial4 +Location PurchasedLocationImperial5 +Location PurchasedLocationImperial6 +Location PurchasedLocationImperial7 +Location PurchasedLocationImperial8 +Location PurchasedLocationImperial9 +Location PurchasedLocationImperial10 +Location PurchasedLocationImperial11 +Location PurchasedLocationImperial12 +Location PurchasedLocationImperial13 +Location PurchasedLocationImperial14 +Location PurchasedLocationImperial15 +Location PurchasedLocationImperial16 +Location PurchasedLocationImperial17 +Location PurchasedLocationImperial18 +Location PurchasedLocationImperial19 +Location PurchasedLocationImperial20 + + +Location PurchasedLocationSons1 +Location PurchasedLocationSons2 +Location PurchasedLocationSons3 +Location PurchasedLocationSons4 +Location PurchasedLocationSons5 +Location PurchasedLocationSons6 +Location PurchasedLocationSons7 +Location PurchasedLocationSons8 +Location PurchasedLocationSons9 +Location PurchasedLocationSons10 +Location PurchasedLocationSons11 +Location PurchasedLocationSons12 +Location PurchasedLocationSons13 +Location PurchasedLocationSons14 +Location PurchasedLocationSons15 +Location PurchasedLocationSons16 +Location PurchasedLocationSons17 +Location PurchasedLocationSons18 +Location PurchasedLocationSons19 +Location PurchasedLocationSons20 + +Location PurchasedLocationBothFactions1 +Location PurchasedLocationBothFactions2 +Location PurchasedLocationBothFactions3 +Location PurchasedLocationBothFactions4 +Location PurchasedLocationBothFactions5 +Location PurchasedLocationBothFactions6 +Location PurchasedLocationBothFactions7 +Location PurchasedLocationBothFactions8 + + + +Event OnInit() + CWs = CW as CWScript + +; CWScript.Log("CWCampaignScript", " OnInit() setting default property values.", 0, True, True) + + AcceptDays = 5 + MissionDays = 2 + ResolutionPhase = 4 + + MissionAcceptancePollWait = 5 ;wait this many seconds inside the while loop in PollForMissionAcceptance() function + + AttackDeltaBonusForKillingCapitalGarrison = 2 + AttackDeltaGarrisonValueModifierForDestroyingResource = 0.50 ;destroying the resource object at a garrison halves it value + + + + ;*** !!! *** !!! TEMPORARY HACK UNTIL WE GET ACTIVATORS IN AS OBJECT TYPES -- these should be set in editor + ResourceObjectFarm = Game.GetForm(0X0001DA07) ;**** !!!! **** !!!!! THIS IS TEMPORARY WORK AROUND UNTIL WE GET ACTIVATOR OBJECTS IN PAPYRUS -- when that happens this property will be set in the editor in the CWCampaign quest + ResourceObjectMill = Game.GetForm(0X0001DA0C) ;**** !!!! **** !!!!! THIS IS TEMPORARY WORK AROUND UNTIL WE GET ACTIVATOR OBJECTS IN PAPYRUS -- when that happens this property will be set in the editor in the CWCampaign quest + ResourceObjectMine = Game.GetForm(0X0001DA0D) ;**** !!!! **** !!!!! THIS IS TEMPORARY WORK AROUND UNTIL WE GET ACTIVATOR OBJECTS IN PAPYRUS -- when that happens this property will be set in the editor in the CWCampaign quest + ;*** !!! *** !!! + +EndEvent + + +Function ResetCampaign() + +; CWScript.Log("CWCampaignScript", " ResetCampaign() resetting property values.") + Mission1Type = 0 + Mission2Type = 0 + Mission3Type = 0 + + acceptedHooks = 0 + acceptedMission = 0 + + completedMission = 0 + failedMission = 0 + + ownerPatrol1 = 0 + ownerPatrol2 = 0 + ownerPatrol3 = 0 + ownerPatrol4 = 0 + ownerPatrol5 = 0 + + unsetPurchasedLocations() + + attackDeltaMissionBonus = 0 + + nextPhaseDay = GameDaysPassed.value + acceptDays ;init value (note this is immediately updated again in stage 150, that's fine.) + + CWCampaignPhase.value = 0 ;reset global (note this is immediately incremented to 1 by stage 150) + resolveOffscreen = 0 ;reset variable + +EndFunction + +Function PurchaseGarrisons() +{Depending on the CW.PurchaseDelta assign various garrisons and patrols to the attacker and defender.} + + ;If PurchaseDelta is > 0 it means the attackers have the advantage and can purchase additional garrisons and patrols, if the PurchaseDelta < 0 it means the defenders have the advantage and have all the garrisons and can purchase additional patrols + +; CWScript.Log("CWCampaignScript", " PurchaseGarrisons() begining to purchase garrisons. Starting PurchaseDelta = " + CWs.PurchaseDelta) + + if CWDebugSkipPurchase.value == 1 +; CWScript.Log("CWCampaignScript", ": CWDebugSkipPurchase == 1, we are skipping call to PurchaseGarrison()", 1) + return + EndIf + + unsetPurchasedLocations() ;### used with CallSetOwnerForPurchasedLocations() -- this would be easier if we had arrays + + + ;## 4-16-2010 -- jduvall + ;NOTE: Purchasing used to happen before resetting the defender only, camps, and patrols... I don't think there was any particular reason to do this, and since things go a little faster if the defender only stuff goes first because it includes the capital which takes the longest to process, I am now putting it first through the SetOwner() switchboard, it'll process its stuff while other garrisons are also being processed + ;Hopefully this doesn't break anythingm if it does just but the "reset" stuff back below the "Purchased" stuff + ;## ----------------------------- + + ;"Purchased" THINGS THAT DON'T GET PURCHASED WITH ATTACK DELTA -- everything gets put in PurchasedLocationXXXn variables simulating an array -- see CallSetOwnerForPurchasedLocations() + ;Reset the defender only garrisons + ResetDefenderOnlyGarrisons() + + ;Reset the camps + ResetCamps() + + ;reset the shared Patrols location + ResetPatrols() + + + ;PURCHASE GARRISONS AND PATROLS -- everything gets put in PurchasedLocationXXXn variables simulating an array -- see CallSetOwnerForPurchasedLocations() + ;Attempt to purchase garrisons + PurchaseGarrisonLocationAlias(Garrison1) + PurchaseGarrisonLocationAlias(Garrison2) + PurchaseGarrisonLocationAlias(Garrison3) + PurchaseGarrisonLocationAlias(Garrison4) + + PurchaseGarrisonLocationAlias(Fort) + + ;Purchase additional patrols if there is any AttackDelta left: see EnablePatrols() call below + ownerPatrol1 = PurchasePatrolAndReturnNewOwner(1) + ownerPatrol2 = PurchasePatrolAndReturnNewOwner(2) + ownerPatrol3 = PurchasePatrolAndReturnNewOwner(3) + ownerPatrol4 = PurchasePatrolAndReturnNewOwner(4) + ownerPatrol5 = PurchasePatrolAndReturnNewOwner(5) + + ;ENABLE THE PURCHASED PATROLS -- not these don't get passed into to SetOwner() via a PurchasedLocationXXXn variable, because these patrols are just turned on/off by toggling xmarkers, see the EnablePatrols() function below. + ;Enable patrols that have been purchased by enabling the proper enable markers + EnablePatrols() + + CallSetOwnerForPurchasedLocations() ;### Calls CWs.SetOwner() for each of the purchased locations -- this would be easier if we had arrays + + +EndFunction + + +Function PurchaseGarrisonLocationAlias(LocationAlias GarrisonAlias) +{Calls PurchaseGarrisonLocation() with the location of the supplied alias, if the alias isn't empty} + Location Loc = GarrisonAlias.Getlocation() + + If Loc != None + PurchaseGarrisonLocation(Loc) + EndIf + +EndFunction + +Function PurchaseGarrisonLocation(Location GarrisonLocation) +{If attacker has enough attack points (ie a large enough positive value in CW.PurchaseDelta) award the garrison ownership to attacker and subtract Purchase Delta, otherwise award to the defender.} + int cost = GarrisonLocation.GetKeywordData(CWCost) as int + int newOwner ;1 = Imperials, 2 = Sons -- will correspond to Attacker and Defender property on CWScript attached to CW quest + + If CWs.PurchaseDelta >= Cost ;award to attacker + newOwner = CWs.Attacker + CWs.PurchaseDelta = (CWs.PurchaseDelta - cost) + GarrisonLocation.SetKeywordData(CWPurchasedByAttacker, 1) +; CWScript.Log("CWCampaignScript", " PurchaseGarrison() purchasing " + GarrisonLocation + " for attacker(" + CWs.FactionName(newOwner) + ") and flagged for reset") + + Else ;award to defender + newOwner = CWs.Defender +; CWScript.Log("CWCampaignScript", " PurchaseGarrison() purchasing " + GarrisonLocation + " for defender(" + CWs.FactionName(newOwner) + ") and flagged for reset") + GarrisonLocation.SetKeywordData(CWPurchasedByAttacker, 0) + ;There is no cost for the defender to purchase a garrison... he owns it by default + + EndIf + + SetPurchasedLocation(GarrisonLocation, NewOwner) + +EndFunction + +Function unsetPurchasedLocations() + PurchasedLocationImperial1 = None + PurchasedLocationImperial2 = None + PurchasedLocationImperial3 = None + PurchasedLocationImperial4 = None + PurchasedLocationImperial5 = None + PurchasedLocationImperial6 = None + PurchasedLocationImperial7 = None + PurchasedLocationImperial8 = None + PurchasedLocationImperial9 = None + PurchasedLocationImperial10 = None + PurchasedLocationImperial11 = None + PurchasedLocationImperial12 = None + PurchasedLocationImperial13 = None + PurchasedLocationImperial14 = None + PurchasedLocationImperial15 = None + PurchasedLocationImperial16 = None + PurchasedLocationImperial17 = None + PurchasedLocationImperial18 = None + PurchasedLocationImperial19 = None + PurchasedLocationImperial20 = None + + PurchasedLocationSons1 = None + PurchasedLocationSons2 = None + PurchasedLocationSons3 = None + PurchasedLocationSons4 = None + PurchasedLocationSons5 = None + PurchasedLocationSons6 = None + PurchasedLocationSons7 = None + PurchasedLocationSons8 = None + PurchasedLocationSons9 = None + PurchasedLocationSons10 = None + PurchasedLocationSons11 = None + PurchasedLocationSons12 = None + PurchasedLocationSons13 = None + PurchasedLocationSons14 = None + PurchasedLocationSons15 = None + PurchasedLocationSons16 = None + PurchasedLocationSons17 = None + PurchasedLocationSons18 = None + PurchasedLocationSons19 = None + PurchasedLocationSons20 = None + + PurchasedLocationBothFactions1 = None + PurchasedLocationBothFactions2 = None + PurchasedLocationBothFactions3 = None + PurchasedLocationBothFactions4 = None + PurchasedLocationBothFactions5 = None + PurchasedLocationBothFactions6 = None + PurchasedLocationBothFactions7 = None + PurchasedLocationBothFactions8 = None +EndFunction + +Function SetPurchasedLocation(Location LocationThatWasPurchased, int OwningFaction) +; CWScript.Log("CWCampaignScript", " SetPurchasedLocation() LocationThatWasPurchased: " + LocationThatWasPurchased + ", OwningFaction:(" + OwningFaction + ")") + + if owningFaction == CWs.iImperials + if !PurchasedLocationImperial1 + PurchasedLocationImperial1 = LocationThatWasPurchased + + elseif !PurchasedLocationImperial2 + PurchasedLocationImperial2 = LocationThatWasPurchased + + elseif !PurchasedLocationImperial3 + PurchasedLocationImperial3 = LocationThatWasPurchased + + elseif !PurchasedLocationImperial4 + PurchasedLocationImperial4 = LocationThatWasPurchased + + ElseIf !PurchasedLocationImperial5 + PurchasedLocationImperial5 = LocationThatWasPurchased + + ElseIf !PurchasedLocationImperial6 + PurchasedLocationImperial6 = LocationThatWasPurchased + + ElseIf !PurchasedLocationImperial7 + PurchasedLocationImperial7 = LocationThatWasPurchased + + ElseIf !PurchasedLocationImperial8 + PurchasedLocationImperial8 = LocationThatWasPurchased + + ElseIf !PurchasedLocationImperial9 + PurchasedLocationImperial9 = LocationThatWasPurchased + + ElseIf !PurchasedLocationImperial10 + PurchasedLocationImperial10 = LocationThatWasPurchased + + Elseif !PurchasedLocationImperial11 + PurchasedLocationImperial11 = LocationThatWasPurchased + + elseif !PurchasedLocationImperial12 + PurchasedLocationImperial12 = LocationThatWasPurchased + + elseif !PurchasedLocationImperial13 + PurchasedLocationImperial13 = LocationThatWasPurchased + + elseif !PurchasedLocationImperial14 + PurchasedLocationImperial14 = LocationThatWasPurchased + + ElseIf !PurchasedLocationImperial15 + PurchasedLocationImperial15 = LocationThatWasPurchased + + ElseIf !PurchasedLocationImperial16 + PurchasedLocationImperial16 = LocationThatWasPurchased + + ElseIf !PurchasedLocationImperial17 + PurchasedLocationImperial17 = LocationThatWasPurchased + + ElseIf !PurchasedLocationImperial18 + PurchasedLocationImperial18 = LocationThatWasPurchased + + ElseIf !PurchasedLocationImperial19 + PurchasedLocationImperial19 = LocationThatWasPurchased + + ElseIf !PurchasedLocationImperial20 + PurchasedLocationImperial20 = LocationThatWasPurchased + + Else +; CWScript.Log("CWCampaignScript", " ERROR!!! SetPurchasedLocation() ran out of PurchaseLocationXXXn variables. LocationThatWasPurchased: " + LocationThatWasPurchased + ", OwningFaction: " + OwningFaction, 2 ) + + EndIf + + elseif owningFaction == CWs.iSons + + if !PurchasedLocationSons1 + PurchasedLocationSons1 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons2 + PurchasedLocationSons2 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons3 + PurchasedLocationSons3 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons4 + PurchasedLocationSons4 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons5 + PurchasedLocationSons5 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons6 + PurchasedLocationSons6 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons7 + PurchasedLocationSons7 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons8 + PurchasedLocationSons8 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons9 + PurchasedLocationSons9 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons10 + PurchasedLocationSons10 = LocationThatWasPurchased + + Elseif !PurchasedLocationSons11 + PurchasedLocationSons11 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons12 + PurchasedLocationSons12 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons13 + PurchasedLocationSons13 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons14 + PurchasedLocationSons14 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons15 + PurchasedLocationSons15 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons16 + PurchasedLocationSons16 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons17 + PurchasedLocationSons17 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons18 + PurchasedLocationSons18 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons19 + PurchasedLocationSons19 = LocationThatWasPurchased + + ElseIf !PurchasedLocationSons20 + PurchasedLocationSons20 = LocationThatWasPurchased + + Else +; CWScript.Log("CWCampaignScript", " ERROR!!! SetPurchasedLocation() ran out of PurchaseLocationXXXn variables. LocationThatWasPurchased: " + LocationThatWasPurchased + ", OwningFaction: " + OwningFaction, 2 ) + + EndIf + + ElseIf owningFaction == CWs.iBothFactions + + if !PurchasedLocationBothFactions1 + PurchasedLocationBothFactions1 = LocationThatWasPurchased + + ElseIf !PurchasedLocationBothFactions2 + PurchasedLocationBothFactions2 = LocationThatWasPurchased + + ElseIf !PurchasedLocationBothFactions3 + PurchasedLocationBothFactions3 = LocationThatWasPurchased + + ElseIf !PurchasedLocationBothFactions4 + PurchasedLocationBothFactions4 = LocationThatWasPurchased + + ElseIf !PurchasedLocationBothFactions5 + PurchasedLocationBothFactions5 = LocationThatWasPurchased + + ElseIf !PurchasedLocationBothFactions6 + PurchasedLocationBothFactions6 = LocationThatWasPurchased + + ElseIf !PurchasedLocationBothFactions7 + PurchasedLocationBothFactions7 = LocationThatWasPurchased + + ElseIf !PurchasedLocationBothFactions8 + PurchasedLocationBothFactions8 = LocationThatWasPurchased + + Else +; CWScript.Log("CWCampaignScript", " ERROR!!! SetPurchasedLocation() ran out of PurchaseLocationXXXn variables. LocationThatWasPurchased: " + LocationThatWasPurchased + ", OwningFaction: " + OwningFaction, 2 ) + + EndIf + + + Else +; CWScript.Log("CWCampaignScript", " ERROR!!! SetPurchasedLocation() Recieved an unexpected value for OwningFaction. Expected 1, 2 or 3, got:" + OwningFaction, 2 ) + + EndIf + + +EndFunction + +Function CallSetOwnerForPurchasedLocations() + + ;SetOwner() takes a max of 8 locations, so we call it until we are done with all the locations in our "arrays" + + ;setOwner for Imperial garrisons + if PurchasedLocationImperial1 + CWs.setOwner(PurchasedLocationImperial1, CWs.iImperials, PurchasedLocationImperial2, PurchasedLocationImperial3, PurchasedLocationImperial4, PurchasedLocationImperial5, PurchasedLocationImperial6, PurchasedLocationImperial7, PurchasedLocationImperial8) + EndIf + + if PurchasedLocationImperial9 + CWs.setOwner(PurchasedLocationImperial9, CWs.iImperials, PurchasedLocationImperial10, PurchasedLocationImperial11, PurchasedLocationImperial12, PurchasedLocationImperial13, PurchasedLocationImperial14, PurchasedLocationImperial15, PurchasedLocationImperial16) + EndIf + + if PurchasedLocationImperial17 + CWs.setOwner(PurchasedLocationImperial17, CWs.iImperials, PurchasedLocationImperial18, PurchasedLocationImperial19, PurchasedLocationImperial20) + EndIf + + ;setOwner for Sons garrisons + if PurchasedLocationSons1 + CWs.setOwner(PurchasedLocationSons1, CWs.iSons, PurchasedLocationSons2, PurchasedLocationSons3, PurchasedLocationSons4, PurchasedLocationSons5, PurchasedLocationSons6, PurchasedLocationSons7, PurchasedLocationSons8) + EndIf + + if PurchasedLocationSons9 + CWs.setOwner(PurchasedLocationSons9, CWs.iSons, PurchasedLocationSons10, PurchasedLocationSons11, PurchasedLocationSons12, PurchasedLocationSons13, PurchasedLocationSons14, PurchasedLocationSons15, PurchasedLocationSons16) + EndIf + + if PurchasedLocationSons17 + CWs.setOwner(PurchasedLocationSons17, CWs.iSons, PurchasedLocationSons18, PurchasedLocationSons19, PurchasedLocationSons20) + EndIf + + ;setOwner for garrisons owned by both (the one patrol location) + if PurchasedLocationBothFactions1 + CWs.setOwner(PurchasedLocationBothFactions1, CWs.iBothFactions, PurchasedLocationBothFactions2, PurchasedLocationBothFactions3, PurchasedLocationBothFactions4, PurchasedLocationBothFactions5, PurchasedLocationBothFactions6, PurchasedLocationBothFactions7, PurchasedLocationBothFactions8) + EndIf + +EndFunction + + +Function ResetDefenderOnlyGarrisons() +; CWScript.Log("CWCampaignScript", " ResetDefenderOnlyGarrisons() 'purchasing' aliases Captial & GarrisonDefenderOnly1-6 (if not empty)") + + ResetDefenderOnlyGarrison(1) + ResetDefenderOnlyGarrison(2) + ResetDefenderOnlyGarrison(3) + ResetDefenderOnlyGarrison(4) + ResetDefenderOnlyGarrison(5) + ResetDefenderOnlyGarrison(6) + +; CWScript.Log("CWCampaignScript", " ResetDefenderOnlyGarrisons() calling SetPurchasedLocation() for Capital" + Capital.GetLocation() + " to be owned by defender(" + CWs.FactionName(CWs.Defender) + ").") + SetPurchasedLocation(Capital.GetLocation(), CWs.Defender) + + +EndFunction + +Function ResetDefenderOnlyGarrison(Int GarrisonToReset) +{Calls ReturnLocationForDefenderOnlyGarrison and (if not None) sets the CWOwner keyword data on the location to be -Defender.} + + Location Garrison = ReturnLocationForDefenderOnlyGarrison(GarrisonToReset) + + if Garrison != None +; CWScript.Log("CWCampaignScript", " ResetDefenderOnlyGarrisons() calling SetPurchasedLocation() for GarrisonDefenderOnly" + GarrisonToReset + " to be owned by defender(" + CWs.FactionName(CWs.Defender) + ").") + + SetPurchasedLocation(Garrison, CWs.Defender) + + Else + ;Do nothing + EndIf + +EndFunction + +location Function ReturnLocationForDefenderOnlyGarrison(int GarrisonToGet) +{Refturns the Location of the GarrisonDefenderOnlyX location alias corresponding to the supplied Int} + + if GarrisonToGet == 1 + return GarrisonDefenderOnly1.Getlocation() + + elseif GarrisonToGet == 2 + return GarrisonDefenderOnly2.Getlocation() + + elseif GarrisonToGet == 3 + return GarrisonDefenderOnly3.Getlocation() + + elseif GarrisonToGet == 4 + return GarrisonDefenderOnly4.Getlocation() + + elseif GarrisonToGet == 5 + return GarrisonDefenderOnly5.Getlocation() + + elseif GarrisonToGet == 6 + return GarrisonDefenderOnly6.Getlocation() + else + + EndIf + +EndFunction + + +Function ResetCamps() +{Sets keyword data CWOwner on CampImperial and CampSons location aliases to cause them to reset} + if CWs.iImperials == CWs.Attacker +; CWScript.Log("CWCampaignScript", " ResetCamps() calling SetPurchasedLocation() for CampImperial locaion alias.") + + SetPurchasedLocation(CampImperial.GetLocation(), CWs.iImperials) + +; CWScript.Log("CWCampaignScript", " ResetCamps() disabling CampEnableSons.") + CampEnableSons.GetReference().disable() + + + Else ;Sons are attacking +; CWScript.Log("CWCampaignScript", " ResetCamps() calling SetPurchasedLocation() CampSons locaion alias.") + + SetPurchasedLocation(CampSons.GetLocation(), CWs.iSons) + +; CWScript.Log("CWCampaignScript", " ResetCamps() disabling CampEnableImperial.") + CampEnableImperial.GetReference().disable() + + endif + + +EndFunction + +int Function PurchasePatrolAndReturnNewOwner(int WhichPatrolToPurchase) +{Returns an int corresponding to faction that should own. If there is enough remaining positive or negative points in PurchaseDelta, purchase a patrol for the attacker (if positive) or defender (if negative)} + int cost = CWs.iCostPatrol + int newOwner ;1 = Imperials, 2 = Sons -- will correspond to Attacker and Defender property on CWScript attached to CW quest + + If CWs.PurchaseDelta >= Cost ;award to attacker, decrease the PurchaseDelta toward 0 + newOwner = CWs.Attacker + CWs.PurchaseDelta = (CWs.PurchaseDelta - cost) +; CWScript.Log("CWCampaignScript", " PurchasePatrolAndReturnNewOwner() purchasing Patrol" + WhichPatrolToPurchase + " for Attacker (" + CWs.FactionName(NewOwner) + ") New PurchaseDelta =" + CWs.PurchaseDelta) + + Elseif -(CWs.PurchaseDelta) <= -(Cost) ;award to defender, increase the PurchaseDelta toward 0 + newOwner = CWs.Defender + CWs.PurchaseDelta = (CWs.PurchaseDelta + cost) +; CWScript.Log("CWCampaignScript", " PurchasePatrolAndReturnNewOwner() purchasing Patrol" + WhichPatrolToPurchase + " for Defender (" + CWs.FactionName(NewOwner) + ") New PurchaseDelta =" + CWs.PurchaseDelta) + + Else ;award to no one + newOwner = 0 +; CWScript.Log("CWCampaignScript", " PurchasePatrolAndReturnNewOwner() not purchasing Patrol" + WhichPatrolToPurchase + " for anyone. Not enough PurchaseDelta: " + CWs.PurchaseDelta) + + EndIf + + return newOwner + +EndFunction + +Function ResetPatrols() +; CWScript.Log("CWCampaignScript", " ResetPatrols() calling SetPurchasedLocation(" + Patrols.GetLocation() + ") with owner = 3 (both factions own patrols location).") + + SetPurchasedLocation(Patrols.GetLocation(), CWs.iBothFactions) ;this causes the garrison to reset/change hands, lives in CWScript + +EndFunction + +Function EnablePatrols() + + EnableDefaultPatrols() + + EnablePatrol(1) + EnablePatrol(2) + EnablePatrol(3) + EnablePatrol(4) + EnablePatrol(5) + +EndFunction + +Function EnableDefaultPatrols() + PatrolsDefaultEnableImperial.GetReference().Enable() + PatrolsDefaultEnableSons.GetReference().Enable() + +; CWScript.Log("CWCampaignScript", " EnableDefaultPatrols() enabling ReferenceAliases PatrolsDefaultEnableImperial and PatrolsDefaultEnableSons.") + +EndFunction + +Function EnablePatrol(int WhichPatrolToEnable) +{Calls GetEnableMarkerForPatrol() for patrol supplied as an Int, and then enables it.} + ObjectReference EnableMarker + + EnableMarker = GetEnableMarkerForPatrol(WhichPatrolToEnable) + + If EnableMarker != None + EnableMarker.Enable() +; CWScript.Log("CWCampaignScript", " EnablePatrol() enabling " + EnableMarker) + Else +; CWScript.Log("CWCampaignScript", " EnablePatrol() not enabling the patrol #" + WhichPatrolToEnable + " for either faction. Which should mean that neither own it.") + EndIf + +EndFunction + +ObjectReference Function GetEnableMarkerForPatrol(int WhichPatrol) +{Returns the ObjectReference for patrol supplied as an Int} + if WhichPatrol == 1 + if OwnerPatrol1 == CWs.iImperials + return PatrolsEnableImperial1.GetReference() + elseif OwnerPatrol1 == CWs.iSons + return PatrolsEnableSons1.GetReference() + else + return None + endif + + elseif WhichPatrol == 2 + if OwnerPatrol2 == CWs.iImperials + return PatrolsEnableImperial2.GetReference() + elseif OwnerPatrol2 == CWs.iSons + return PatrolsEnableSons2.GetReference() + else + return None + endif + + elseif WhichPatrol == 3 + if OwnerPatrol3 == CWs.iImperials + return PatrolsEnableImperial3.GetReference() + elseif OwnerPatrol3 == CWs.iSons + return PatrolsEnableSons3.GetReference() + else + return None + endif + + elseif WhichPatrol == 4 + if OwnerPatrol4 == CWs.iImperials + return PatrolsEnableImperial4.GetReference() + elseif OwnerPatrol4 == CWs.iSons + return PatrolsEnableSons4.GetReference() + else + return None + endif + + elseif WhichPatrol == 5 + if OwnerPatrol5 == CWs.iImperials + return PatrolsEnableImperial5.GetReference() + elseif OwnerPatrol5 == CWs.iSons + return PatrolsEnableSons5.GetReference() + else + return None + endif + Else +; CWScript.Log("CWCampaignScript", " GetEnableMarkerForPatrol() expected an Int 1-5, instead got " + WhichPatrol) + return None + EndIf + +EndFunction + + + +Function SetCWCampaignFieldCOAliases() +{Forces named field COs into FieldCO and generic enemy field COs into EnemyFieldCO, enables the EnemyFieldCO and disables the other non-used generic field CO} + + if CWs.playerAllegiance == CWs.iImperials + + if CWs.playerInvolved == 0 +; CWScript.Log("CWCampaignScript", " SetCWCampaignFieldCOAliases() Player Allegience == 1 and PlayerInvolved == 0, so we are Forcing GenericFieldCOImperial into FieldCo, GenericFieldCOSons into EnemyFieldCO, and enabling them both.") + + FieldCO.ForceRefTo(GenericFieldCOImperial.GetReference()) + EnemyFieldCO.ForceRefTo(GenericFieldCOSons.GetReference()) + + GenericFieldCOImperial.GetReference().Enable() + EnemyFieldCO.GetReference().Enable() + + Elseif CWs.playerInvolved == 1 + +; CWScript.Log("CWCampaignScript", " SetCWCampaignFieldCOAliases() is Forcing Rikke into FieldCo, GenericFieldCOSons into EnemyFieldCO, enabling EnemyFieldCO, and disabling GenericFieldCOImperial.") + + FieldCO.ForceRefTo(Rikke.GetReference()) + EnemyFieldCO.ForceRefTo(GenericFieldCOSons.GetReference()) + + EnemyFieldCO.GetReference().Enable() + GenericFieldCOImperial.GetReference().Disable() + + Else +; CWScript.Log("CWCampaignScript", "WARNING: SetCWCampaignFieldCOAliases() expected 0 or 1 for CWScript PlayerInvolved, instead found:" + CWs.playerInvolved, 2) + + + EndIf + + Elseif CWs.playerAllegiance == CWs.iSons + + if CWs.playerInvolved == 0 +; CWScript.Log("CWCampaignScript", " SetCWCampaignFieldCOAliases() playerAllegiance == 2 and PlayerInvolved == 0, so we are Forcing GenericFieldCOSons into FieldCo, GenericFieldCOImperial into EnemyFieldCO, and enabling them both.") + + FieldCO.ForceRefTo(GenericFieldCOSons.GetReference()) + EnemyFieldCO.ForceRefTo(GenericFieldCOImperial.GetReference()) + + GenericFieldCOImperial.GetReference().Enable() + EnemyFieldCO.GetReference().Enable() + + Elseif CWs.playerInvolved == 1 + +; CWScript.Log("CWCampaignScript", " SetCWCampaignFieldCOAliases() is Forcing Galmar into FieldCo, GenericFieldCOImperial into EnemyFieldCO, enabling EnemyFieldCO, and disabling GenericFieldCOSons.") + + FieldCO.ForceRefTo(Galmar.GetReference()) + EnemyFieldCO.ForceRefTo(GenericFieldCOImperial.GetReference()) + + EnemyFieldCO.GetReference().Enable() + GenericFieldCOSons.GetReference().Disable() + + Else +; CWScript.Log("CWCampaignScript", "WARNING: SetCWCampaignFieldCOAliases() expected 0 or 1 for CWScript PlayerInvolved, instead found:" + CWs.playerInvolved, 2) + + EndIf + + Else +; CWScript.Log("CWCampaignScript", "WARNING: SetCWCampaignFieldCOAliases expected playerAllegience to be 1 or 2, got " + CWs.playerAllegiance, 2) + + EndIf + +EndFunction + +Function AdvanceCampaignPhase(int OptionalPhaseToSetTo = -1) +{Called when needing to advance the campaign to the next phase, and start new missions} + + ;* The reason for this weird if / while loop below... + ;Phases advance 'automatically': mission accept timers and mission fail timers expire setting mission quest stages that call AdvanceCampaignPhase() and then shut down. + ;However, this function is also called in dialogue with the FactionLeader the first time the player is joining a campaign to reset the campaign to the first phase (via passing a "1" in for the optional param) + ;It's possible that while in dialogue, the campaign phase could advance automatically and the resolution happens off screen, in the middle of the FactionLeader telling us to go meet the field officer - that'd be really weird. + ;We don't want him to say go join this campaign, and then immediately it fails. + ;So this while loop prevents the campaign from advancing at least until after the player leaves the town with the FactionLeader in it, since the player realizes this is a dynamic system, he'll hopefully forgive that weirdness if the campaign ends soon after leaving. + ;If the campaign is starting fresh (ie the CWCampaignPhase is 0) we don't care if the player is standing right in front of the FactionLeader, otherwise we'd never get start the campaign if the player hangs out in the same town with FactionLeader + + ;* See rationale for this above + if CWCampaignPhase.value != 0 && OptionalPhaseToSetTo == -1 ;ie the default call, not when it's called in dialogue with the faction leader the first time the player is joining a campaign in the civil war + while CWs.AliasFactionLeader.GetReference().getCurrentLocation().IsSameLocation(Game.GetPlayer().getCurrentLocation(), LocTypeHabitation) +; CWScript.Log("CWCampaignScript", " AdvanceCampaignPhase() WAITING -PLAYER NEARBY: in a while loop wait until after player and Faction leader aren't in the same LocTypeHabitation location.", 1) +;*** !!! *** IF WE EVER GET A WAIT MENU, THEN WE NEED TO NOT CARE IF THE PLAYER IS IN THE SAME LOCATION IF HE IS ALSO WAITING + utility.wait(10) + + EndWhile + EndIf + +; CWScript.Log("CWCampaignScript", " AdvanceCampaignPhase() running.") + + if OptionalPhaseToSetTo > 0 + CWCampaignPhase.value = OptionalPhaseToSetTo +; CWScript.Log("CWCampaignScript", " AdvanceCampaignPhase() forced CWCampaignPhase global to " + CWCampaignPhase.value ) + Else + ;Increment the phase + CWCampaignPhase.value += 1 +; CWScript.Log("CWCampaignScript", " AdvanceCampaignPhase() incremented CWCampaignPhase global to " + CWCampaignPhase.value ) + EndIf + + if CWs.debugStartingCampaignPhase != 0 && CWCampaignPhase.value < CWs.debugStartingCampaignPhase + CWCampaignPhase.value = CWs.debugStartingCampaignPhase +; CWScript.Log("CWCampaignScript", " AdvanceCampaignPhase() forcing CWCampaignPhase to debugStartingCampaignPhase " + CWCampaignPhase.value ) + EndIf + + if DebugOn.value == 1 + debug.Notification("CWCampaignPhase: " + CWCampaignPhase.value) + EndIf + + ;Increment the NextPhaseDay + NextPhaseDay = GameDaysPassed.value + AcceptDays +; CWScript.Log("CWCampaignScript", " AdvanceCampaignPhase() set CWCampaignPhase NextPhaseDay to " + NextPhaseDay + " ( = GameDaysPassed(" + GameDaysPassed.value + ") AcceptDays(" + AcceptDays + ")." ) + + ;Reset Mission tracking properties + Mission1Type = 0 + Mission2Type = 0 + Mission3Type = 0 + AcceptedHooks = 0 + AcceptedMission = 0 + + ;set current attack delta + SetCurrentAttackDelta() + + ;Start missions: + StartMissions() + + if DebugOn.value == 1 + debug.MessageBox("CWCampaignScript: Ready to start campaign.") + EndIf + +EndFunction + + + + +Function StartResolutionMission() +{Starts the proper resolution mission, checking if the Capital is a city or not, and whether the player should be attacking or defending.} + + ;start an Attack the Capital Settlement resolution quest + ;createEvent CWResolution01Start zBogusLocation FieldCO CampaignStartMarker + + ;start a Defend the Capital Settlement resolution quest + ;createEvent CWResolution02Start zBogusLocation FieldCO CampaignStartMarker + + If Capital.GetLocation().HasKeyword(LocTypeCity) && CWs.debugTreatCityCapitalsAsTowns == 0 ;capital is a city (note the debugTreatCityCapitalsAsTowns) + + CWSiegeStart.SendStoryEvent(Capital.GetLocation()) ;the story manager handles checking the location, the player's allegiance and who is attacking to start the quests + + ; if Capital.GetLocation() == CWs.WhiterunLocation ;ADD || OTHER CITY HERE +; ; CWScript.Log("CWCampaignScript", " StartResolutionMission() starting attack on Whiterun.") + ; CWSiegeStart.SendStoryEvent(Capital.GetLocation()) ;the story manager handles checking the location, the player's allegiance and who is attacking to start the quests + ; + ; Else ;SOME OTHER NOT YET IMPLEMENTED CITY +; ; CWScript.Log("CWCampaignScript", " StartResolutionMission() needs to start an Attack on a Capital CITY. Will RESOLVE OFFSCREEN.") + ; debug.MessageBox("CWCampaignScript StartResolutionMission() needs to start an Attack on a Capital CITY. RESOLVE OFFSCREEN.") + ; CWs.ResolveOffscreen(GetCurrentAttackDelta()) + ; + ; EndIf + + Else ;capital is not a city + if CWs.playerAllegiance == CWs.Attacker + ;start an Attack the Capital Settlement resolution quest +; CWScript.Log("CWCampaignScript", " StartResolutionMission() starting Resolution01 for " + Capital.Getlocation()) + CWResolution01Start.SendStoryEvent(Capital.Getlocation(), FieldCO.GetReference(), CampaignStartMarker.GetReference()) + + Else + ;start an Defend the Capital Settlement resolution quest +; CWScript.Log("CWCampaignScript", " StartResolutionMission() starting Resolution02 for " + Capital.Getlocation()) + CWResolution02Start.SendStoryEvent(Capital.Getlocation(), FieldCO.GetReference(), CampaignStartMarker.GetReference()) + + EndIf + + EndIf + +EndFunction + + +function setCurrentAttackDelta() + + CurrentAttackDelta = GetCurrentAttackDelta() + +EndFunction + + +int Function GetCurrentAttackDelta() +{Returns the current Attack Delta based on situation affected by players actions on the ground. Garrisons don't provide points if all the soldiers are dead, or half points if a resource object is destroyed, plus any misc modifiers for doing special missions.} + + float myCurrentAttackDelta + +; CWScript.Log("CWCampaignScript", " GetmyCurrentAttackDelta() is running.") + + ;Get points for capital garrison + myCurrentAttackDelta += GetAttackDeltaPointsForCapital(Capital.GetLocation()) + + ;Get points for garrisons and their resource objects --- Detailed note about resource objects: A garrison may have more than one resource object in it... we are only testing against the one that filled the alias. Effectively this means the player must get lucky, or destroy all of the resources to get the bonus. This shouldn't matter greatly. + myCurrentAttackDelta += GetAttackDeltaPointsForDefenderOnlyGarrison(GarrisonDefenderOnly1.GetLocation(), GarrisonDefenderOnly1ResourceObject.GetReference()) + myCurrentAttackDelta += GetAttackDeltaPointsForDefenderOnlyGarrison(GarrisonDefenderOnly2.GetLocation(), GarrisonDefenderOnly2ResourceObject.GetReference()) + myCurrentAttackDelta += GetAttackDeltaPointsForDefenderOnlyGarrison(GarrisonDefenderOnly3.GetLocation(), GarrisonDefenderOnly3ResourceObject.GetReference()) + myCurrentAttackDelta += GetAttackDeltaPointsForDefenderOnlyGarrison(GarrisonDefenderOnly4.GetLocation(), GarrisonDefenderOnly4ResourceObject.GetReference()) + + myCurrentAttackDelta += GetAttackDeltaPointsForGarrison(Garrison1.GetLocation(), Garrison1ResourceObject.GetReference()) + myCurrentAttackDelta += GetAttackDeltaPointsForGarrison(Garrison2.GetLocation(), Garrison2ResourceObject.GetReference()) + myCurrentAttackDelta += GetAttackDeltaPointsForGarrison(Garrison3.GetLocation(), Garrison3ResourceObject.GetReference()) + myCurrentAttackDelta += GetAttackDeltaPointsForGarrison(Garrison4.GetLocation(), Garrison4ResourceObject.GetReference()) + + + ;Get points for Patrols + myCurrentAttackDelta += GetAttackDeltaPointsForPatrols() + + ;Get points for mission bonueses + myCurrentAttackDelta += GetAttackDeltaMissionBonus() + +; CWScript.Log("CWCampaignScript", " GetmyCurrentAttackDelta() is returning myCurrentAttackDelta " + myCurrentAttackDelta + " rounded as int (" + (myCurrentAttackDelta as int) + ") compared to original campaign AttackDelta of " + CWs.AttackDelta) + + return myCurrentAttackDelta as int + +EndFunction + +int Function GetAttackDeltaPointsForCapital(Location CapitalLocation) +{Returns the CurrentAttackDelta points contributed by the capital.} + + ;Note: + ;Since the defender gets the capital garrison for free, in otherwords it's not purchased at the start of the campaign, the defender gets no benefit if the guards are alive. + ;However, if the player killed all the guards there, then we want to give the attacker some bonus points so the player can feel like his actions have had an effect + + If CapitalLocation.GetRefTypeAliveCount(CWSoldier) == 0 +; CWScript.Log("CWCampaignScript", " GetAttackDeltaPointsForCapital() is returning " + AttackDeltaBonusForKillingCapitalGarrison + " points for the CurrentAttackDelta because all the soldiers in the garrison are dead.") + + return AttackDeltaBonusForKillingCapitalGarrison ;set in OnInit() + + else +; CWScript.Log("CWCampaignScript", " GetAttackDeltaPointsForCapital() is returning 0 points for the CurrentAttackDelta because the garrison is intact:" + CapitalLocation ) + return 0 ;There are soldiers alive in the capital, so the attacker is awarded no points + + EndIf + +EndFunction + +float Function GetAttackDeltaPointsForDefenderOnlyGarrison(Location Garrison, ObjectReference ResourceObject) +{Returns the CurrentAttackDelta points contributed by the Garrison and it's ResourceObject.} + ;Note: + ;Since the defender gets the garrison for free, in otherwords it's not purchased at the start of the campaign, the defender gets no benefit if the guards are alive. + ;However, if the player killed all the guards there, or destroyed a resourceObject there, then we want to give the attacker some bonus points so the player can feel like his actions have had an effect + + int BaseGarrisonValue + float GarrisonValue + + If Garrison == None + return 0 + EndIf + + BaseGarrisonValue = Garrison.GetKeywordData(CWCost) as Int + GarrisonValue = BaseGarrisonValue + + if BaseGarrisonValue == CWs.iCostNonContestable +; CWScript.Log("CWCampaignScript", " GetAttackDeltaPointsForDefenderOnlyGarrison() is returning 0 points for the CurrentAttackDelta because Garrison(" + Garrison + ") is Non-Contestable, ie has a CWCost value of:" + BaseGarrisonValue ) + + return 0 + + ElseIf Garrison.GetRefTypeAliveCount(CWSoldier) == 0 +; CWScript.Log("CWCampaignScript", " GetAttackDeltaPointsForDefenderOnlyGarrison() is returning " + BaseGarrisonValue + " points for the CurrentAttackDelta because all the soldiers are dead in Garrison(" + Garrison + ")") + + return BaseGarrisonValue + + ;*** !!! THIS IS SIMILAR BUT NOT IDENTICAL TO ELSEIF IN GetAttackDeltaPointsForGarrison() BELOW + ElseIf (ResourceObject as ResourceObjectScript).IsSabotaged() + + GarrisonValue *= AttackDeltaGarrisonValueModifierForDestroyingResource + +; CWScript.Log("CWCampaignScript", " GetAttackDeltaPointsForDefenderOnlyGarrison() is returning " + GarrisonValue + " points for the CurrentAttackDelta because the resource object is destroyed in the Garrison(" + Garrison + ")") + + return GarrisonValue + + + Else + +; CWScript.Log("CWCampaignScript", " GetAttackDeltaPointsForDefenderOnlyGarrison() is returning 0 points for the CurrentAttackDelta because the garrison is intact:" + Garrison + ")") + return 0 + + EndIf + +EndFunction + +float Function GetAttackDeltaPointsForGarrison(Location Garrison, ObjectReference ResourceObject) +{Returns the CurrentAttackDelta points contributed by the Garrison and it's ResourceObject.} + ;Note: + ;Whoever owns the Garrison gets points for it based on if the resource object is destroyed or not, and if the guards there are alive or not.s so the player can feel like his actions have had an effect + +; CWScript.Log("CWCampaignScript", " GetAttackDeltaPointsForGarrison(Garrison[" + Garrison + "], ResourceObject[" + ResourceObject + "])") + + + int BaseGarrisonValue + float GarrisonValue + + If Garrison == None + return 0 + EndIf + + BaseGarrisonValue = Garrison.GetKeywordData(CWCost) as Int + GarrisonValue = BaseGarrisonValue + + if BaseGarrisonValue == CWs.iCostNonContestable ;Note this shouldn't be the case unless an error has occured setting the cost in the first place, only defender only garrisons should have a CWCost == iCostNonContestable +; CWScript.Log("CWCampaignScript", "WARNING: GetAttackDeltaPointsForGarrison() is returning 0 points for the CurrentAttackDelta because Garrison(" + Garrison + ") UNEXPECTEDLY is Non-Contestable, ie has a CWCost value of:" + BaseGarrisonValue, 2) + + return 0 + + ElseIf Garrison.GetRefTypeAliveCount(CWSoldier) == 0 +; CWScript.Log("CWCampaignScript", " GetAttackDeltaPointsForGarrison() is returning 0 points for the CurrentAttackDelta because all the soldiers are dead in Garrison(" + Garrison + ")") + + return 0 + + ;*** !!! THIS IS SIMILAR BUT NOT IDENTICAL TO ELSEIF IN GetAttackDeltaPointsForDefenderOnlyGarrison() ABOVE + ElseIf (ResourceObject as ResourceObjectScript).IsSabotaged() + + GarrisonValue *= AttackDeltaGarrisonValueModifierForDestroyingResource + +; CWScript.Log("CWCampaignScript", " GetAttackDeltaPointsForGarrison() is returning " + GarrisonValue + " points for the CurrentAttackDelta because the resource object is destroyed in the Garrison(" + Garrison + ")") + + ;DON'T RETURN, to give chance to process the attacker/defender below + + EndIf + + if Math.ABS(Garrison.GetKeywordData(CWOwner) as Int) == CWs.Attacker +; CWScript.Log("CWCampaignScript", " GetAttackDeltaPointsForGarrison() is returning " + GarrisonValue + " points for the CurrentAttackDelta (ie positive value for the Attacker). Garrison:" + Garrison) + + return GarrisonValue + + Else ;owned by Defender + ;only award points if the Defender won it back from the Attacker who purchased it + if Garrison.GetKeywordData(CWPurchasedByAttacker) as Int == 1 +; CWScript.Log("CWCampaignScript", " GetAttackDeltaPointsForGarrison() is returning " + -(GarrisonValue) + " points for the CurrentAttackDelta (ie negative value for the Defender) because he won it back from the Attacker who purchased it. Garrison:" + Garrison) + + return -(GarrisonValue) ;Negative value means in the defender's favor + Else +; CWScript.Log("CWCampaignScript", " GetAttackDeltaPointsForGarrison() is returning 0 points for the CurrentAttackDelta because it is owned by the Defender who did not have to purchase it. Garrison:" + Garrison) + + return 0 + + EndIf + + + + EndIf + +EndFunction + + +int Function GetAttackDeltaPointsForPatrols() +{Returns the sum of the CurrentAttackDelta points contributed by the Patrols for both sides.} + + ;If the patrol is owned, the owner get's points for it if the patrol isn't dead. + + int PatrolValue = CWs.iCostPatrol + int PatrolsAttackDeltaPoints = 0 + + Location PatrolsLoc = Patrols.GetLocation() + + int Attacker = CWs.Attacker + int Defender = CWs.Defender + + if PatrolsLoc.GetRefTypeAliveCount(CWPatrol1) >= 1 + if OwnerPatrol1 == Attacker + PatrolsAttackDeltaPoints += PatrolValue + Elseif OwnerPatrol1 == Defender ;must be explictly owned + PatrolsAttackDeltaPoints += -(PatrolValue) ;negative value means in the defender's favor + EndIf + EndIf + + if PatrolsLoc.GetRefTypeAliveCount(CWPatrol2) >= 1 + if OwnerPatrol2 == Attacker + PatrolsAttackDeltaPoints += PatrolValue + Elseif OwnerPatrol1 == Defender ;must be explictly owned + PatrolsAttackDeltaPoints += -(PatrolValue) ;negative value means in the defender's favor + EndIf + EndIf + + if PatrolsLoc.GetRefTypeAliveCount(CWPatrol3) >= 1 + if OwnerPatrol3 == Attacker + PatrolsAttackDeltaPoints += PatrolValue + Elseif OwnerPatrol1 == Defender ;must be explictly owned + PatrolsAttackDeltaPoints += -(PatrolValue) ;negative value means in the defender's favor + EndIf + EndIf + + if PatrolsLoc.GetRefTypeAliveCount(CWPatrol4) >= 1 + if OwnerPatrol4 == Attacker + PatrolsAttackDeltaPoints += PatrolValue + Elseif OwnerPatrol1 == Defender ;must be explictly owned + PatrolsAttackDeltaPoints += -(PatrolValue) ;negative value means in the defender's favor + EndIf + EndIf + + if PatrolsLoc.GetRefTypeAliveCount(CWPatrol5) >= 1 + if OwnerPatrol5 == Attacker + PatrolsAttackDeltaPoints += PatrolValue + Elseif OwnerPatrol1 == Defender ;must be explictly owned + PatrolsAttackDeltaPoints += -(PatrolValue) ;negative value means in the defender's favor + EndIf + EndIf + +; CWScript.Log("CWCampaignScript", " GetAttackDeltaPointsForPatrols() is returning " + (PatrolsAttackDeltaPoints) + " points for the patrols. If positive it means the Attacker has more living patrols, if negative it means the defender has more living patrols.).") + + return PatrolsAttackDeltaPoints + +EndFunction + +function addAttackDeltaMissionBonus(int valueToAdd) + attackDeltaMissionBonus += valueToAdd +; CWScript.Log("CWCampaignScript", " addAttackDeltaMissionBonus() adding " + valueToAdd + " making AttackDeltaMissionBonus = " + attackDeltaMissionBonus) + +EndFunction + +function subtractAttackDeltaMissionBonus(int valueToSubtract) + attackDeltaMissionBonus += valueToSubtract +; CWScript.Log("CWCampaignScript", " asubtractAttackDeltaMissionBonus() subtracting " + valueToSubtract + " making AttackDeltaMissionBonus = " + attackDeltaMissionBonus) + +EndFunction + +int Function getAttackDeltaMissionBonus() +; CWScript.Log("CWCampaignScript", " getAttackDeltaMissionBonus() returning AttackDeltaMissionBonus: " + attackDeltaMissionBonus) + return attackDeltaMissionBonus + +EndFunction + +int Function GetCountFarms(ReferenceAlias ResourceObject1, ReferenceAlias ResourceObject2, ReferenceAlias ResourceObject3) +{Called by CWMissions. Returns the number of farm resource objects.} + + int count + + If ResourceObject1.GetReference() != None && GetResourceType(ResourceObject1) == 1 + count += 1 + endif + + If ResourceObject2.GetReference() != None && GetResourceType(ResourceObject2) == 1 + count += 1 + endif + + If ResourceObject3.GetReference() != None && GetResourceType(ResourceObject3) == 1 + count += 1 + endif + + return count + +EndFunction + +int Function GetCountMills(ReferenceAlias ResourceObject1, ReferenceAlias ResourceObject2, ReferenceAlias ResourceObject3) +{Called by CWMissions. Returns the number of mill resource objects.} + + int count + + If ResourceObject1.GetReference() != None && GetResourceType(ResourceObject1) == 2 + count += 1 + endif + + If ResourceObject2.GetReference() != None && GetResourceType(ResourceObject2) == 2 + count += 1 + endif + + If ResourceObject3.GetReference() != None && GetResourceType(ResourceObject3) == 2 + count += 1 + endif + + return count + +EndFunction + +int Function GetCountMines(ReferenceAlias ResourceObject1, ReferenceAlias ResourceObject2, ReferenceAlias ResourceObject3) +{Called by CWMissions. Returns the number of mine resource objects.} + + int count + + If ResourceObject1.GetReference() != None && GetResourceType(ResourceObject1) == 3 + count += 1 + endif + + If ResourceObject2.GetReference() != None && GetResourceType(ResourceObject2) == 3 + count += 1 + endif + + If ResourceObject3.GetReference() != None && GetResourceType(ResourceObject3) == 3 + count += 1 + endif + + return count + +EndFunction + +int function GetResourceType(ReferenceAlias ResourceObject) +{Returns an int signifying the resource type: 1 = Farm object, 2 = Mill object, 3 = Mine object} + + ResourceObjectScript ResourceObjectS = ResourceObject.GetReference() as ResourceObjectScript + int type = ResourceObjectS.GetResourceType() + + if type < 1 || type > 3 +; CWScript.Log("CWCampaignScript", " GetResourceType() doesn't know what type to return for ResourceObject, will return 4") + type = 4 + EndIf + +; CWScript.Log("CWCampaignScript", " GetResourceType(" + ResourceObject +") which is objectReference[" + ResourceObject.GetReference() + "]returning type =" + type) + + return type + +EndFunction + + +function ForceFieldHQAliases() +{Forces The capitalHQ, or camp location into the FieldHQ and EnemyFieldHQ aliases based on the player's faction and the attacking faction.} + + int playerAllegiance = CWs.PlayerAllegiance + int Attacker = CWs.Attacker + int ownerContestedHold = CWs.ownerContestedHold + int iImperials = CWs.iImperials + int iSons = CWs.iSons + + + If PlayerAllegiance == ownerContestedHold + FieldHQ.ForceLocationTo(CapitalHQ.GetLocation()) + + ;make the enemy camp as the EnemyFieldHQ + If playerAllegiance == iImperials ;enemy is Sons + EnemyFieldHQ.ForceLocationTo(CampSons.GetLocation()) + + Elseif playerAllegiance == iSons ;enemy is Imperials + EnemyFieldHQ.ForceLocationTo(CampImperial.GetLocation()) + + Else ;unexpected allegiance +; CWScript.Log("CWCampaignScript", "ERROR: ForceFieldHQAliases() expected playerAllegiance to be 1 or 2, instead found " + playerAllegiance, 2) + + EndIf + + + Else ;player's faction is not the owner of the contested hold, so make his camp the fieldHQ and the capital the EnemyFieldHQ + EnemyFieldHQ.ForceLocationTo(CapitalHQ.GetLocation()) + + ;make the player's faction camp as the FieldHQ + If playerAllegiance == iImperials ;player is Sons + FieldHQ.ForceLocationTo(CampImperial.GetLocation()) + + Elseif playerAllegiance == iSons ;player is Imperials + FieldHQ.ForceLocationTo(CampSons.GetLocation()) + + Else ;unexpected allegiance +; CWScript.Log("CWCampaignScript", "ERROR: ForceFieldHQAliases() expected playerAllegiance to be 1 or 2, instead found " + playerAllegiance, 2) + + EndIf + + EndIf + +; CWScript.Log("CWCampaignScript", " ForceFieldHQAliases(): PlayerAllegiance ==" + PlayerAllegiance + ", ownerContestedHold ==" + ownerContestedHold + ", Attacker ==" + Attacker) +; CWScript.Log("CWCampaignScript", " ForceFieldHQAliases(): Set FieldHQ to " + FieldHQ.GetLocation() + ", Set EnemyFieldHQ to " + EnemyFieldHQ.GetLocation()) + +EndFunction + + +Function PlayerJoinsActiveCampaign() +{When player get's involved in a civil war campaign for the first time, we need to roll it back to the begining.} +; CWScript.Log("CWCampaignScript", " PlayerJoinsActiveCampaign() will Call ForceFieldHQAliases(), SetCWCampaignFieldCOAliases, UpdateCWCampaignObjAliases, and AdvanceCampaignPhase(1) ") + ForceFieldHQAliases() + SetCWCampaignFieldCOAliases() + UpdateCWCampaignObjAliases() + AdvanceCampaignPhase(1) ;forces the campaign to "start over" with phase 1 + startTutorialMission() + +EndFunction + +function UpdateCWCampaignObjAliases() +{Forces the aliases in CWCampaignObj quest to have the current references/locations of the related aliases in CWCampaign} +; CWScript.Log("CWCampaignScript", " UpdateCWCampaignObjAliases() forcing CWCampaignObj aliases to match. ") + + CWCampaignObjFieldCO.ForceRefTo(FieldCO.GetReference()) + CWCampaignObjFactionLeader.ForceRefTo(CWs.AliasFactionLeader.GetReference()) + CWCampaignObjCampaignStartMarker.ForceRefTo(CampaignStartMarker.GetReference()) + CWCampaignObjCampaignHold.ForceLocationTo(Hold.GetLocation()) + +EndFunction + +Function startTutorialMission() + int tutorial = CWs.TutorialMissionComplete + +; CWScript.Log("CWCampaignScript", " StartTutorialMission()") + CWMissionTutorialStart.SendStoryEvent(Hold.Getlocation(), CampaignStartMarker.GetReference(), CWMission1Ref) + +EndFunction + +Function stopTutorialMission() + + int secondsWaiting = 0 + + ;This is called by "CWScript FinishCampaign()" + ;In the event that a campaign finishes before the player runs the mission, we need to be sure to completely stop the tutorial mission before the campaign wraps up, so when the next campaign starts we can start the tutorial mission properly. + +; CWScript.Log("CWCampaignScript", " stopTutorialMission() stopping CWMission00") + + CWMission00.stop() + + while CWMission00.IsStopped() == False + Utility.wait(5) + secondsWaiting += 5 +; CWScript.Log("CWCampaignScript", " stopTutorialMission() waiting for CWMission00 to stop. Seconds spent waiting:" + secondsWaiting, 1) + EndWhile + +EndFunction + +;Used by CWCampaignFieldCOScript - see Stage 0 in CWCampaign +ObjectReference Function GetAttackerFieldHQCenterMarker() + + ObjectReference CenterMarkerRef + + if CWs.Attacker == CWs.iImperials + CenterMarkerRef = CampImperialLocationCenterMarker.GetReference() + + elseif CWs.Attacker == CWs.iSons + CenterMarkerRef = CampSonsLocationCenterMarker.GetReference() + + Else +; CWScript.Log("CWCampaignScript", " WARNING: GetAttackerFieldHQCenterMarker() expected CWs.Attacker to be 1 or 2, instead found " + CWs.Attacker, 2, 1, 1) + CenterMarkerRef = none + EndIf + +; CWScript.Log("CWCampaignScript", " GetAttackerFieldHQCenterMarker() returning " + CenterMarkerRef) + + return CenterMarkerRef + +EndFunction + +ObjectReference function GetCapitalHQMarker() + ObjectReference markerRef = CapitalHQMarker.GetReference() + +; CWScript.Log("CWCampaignScript", " GetCapitalHQMarker() returning " + MarkerRef) + + Return MarkerRef + +EndFunction + + +ObjectReference function GetFieldHQMarker() +; CWScript.Log("CWCampaignScript", " GetFieldHQCenterMarker()") + + ObjectReference MarkerRef + + if CWs.PlayerAllegiance == CWs.Attacker + MarkerRef = GetAttackerFieldHQCenterMarker() + + Else + MarkerRef = GetCapitalHQMarker() + + EndIf + +; CWScript.Log("CWCampaignScript", " GetFieldHQMarker() is returning " + MarkerRef) + + Return MarkerRef + +EndFunction + + +ObjectReference function GetEnemyFieldHQMarker() +; CWScript.Log("CWCampaignScript", " GetEnemyFieldHQMarker()") + + ObjectReference MarkerRef + + if CWs.PlayerAllegiance == CWs.Attacker + MarkerRef = GetCapitalHQMarker() ;since player is attacking then the enemy is defending and has the captial hq + + Else + MarkerRef = GetAttackerFieldHQCenterMarker() ;since player is defending then the enemy is attacking + + EndIf + +; CWScript.Log("CWCampaignScript", " GetEnemyFieldHQMarker() is returning " + MarkerRef) + + Return MarkerRef + +EndFunction + + + +;******************************************************************************************************************* +;*** OBSOLETE FUNCTIONS BELOW *** +;******************************************************************************************************************* + +Function StartMissions() + + If CWCampaignPhase.value < ResolutionPhase ;then start normal missions + +; CWScript.Log("CWCampaignScript", " AdvanceCampaignPhase() CWCampaignPhase(" + CWCampaignPhase.value + ") < ResolutionPhase(" + ResolutionPhase + "). Starting Missions.") + + CWMissionStart.SendStoryEvent(Hold.Getlocation(), CampaignStartMarker.GetReference(), CWMission1Ref) + CWMissionStart.SendStoryEvent(Hold.Getlocation(), CampaignStartMarker.GetReference(), CWMission2Ref) + + ;we used to offer three missiosn, now we are only offering two at a time + ;CWMissionStart.SendStoryEvent(Hold.Getlocation(), CampaignStartMarker.GetReference(), CWMission3Ref) + + ((Self as Quest) as CWCampaignPollForMissionAcceptScript).StartPolling() + + ElseIf CWCampaignPhase.value == ResolutionPhase ;then start the resolution Quest + if CWs.TutorialMissionComplete == 0 +; CWScript.Log("CWCampaignScript", " AdvanceCampaignPhase() CWCampaignPhase(" + CWCampaignPhase.value + ") == ResolutionPhase(" + ResolutionPhase + "). Tutorial mission not completed, resolving offscreen.") + CWs.ResolveOffscreen(GetCurrentAttackDelta()) + + Else +; CWScript.Log("CWCampaignScript", " AdvanceCampaignPhase() CWCampaignPhase(" + CWCampaignPhase.value + ") == ResolutionPhase(" + ResolutionPhase + "). Starting Resolution Mission.") + StartResolutionMission() + ((Self as Quest) as CWCampaignPollForMissionAcceptScript).StartPolling() + + EndIf + + Else ; We are trying to advance into a phase after the resolution phase, which means we should resolve the resolution mission off screen +; CWScript.Log("CWCampaignScript", " AdvanceCampaignPhase() CWCampaignPhase(" + CWCampaignPhase.value + ") > ResolutionPhase(" + ResolutionPhase + "). Resolving Resolution Mission OFFSCREEN.") + ((Self as Quest) as CWCampaignPollForMissionAcceptScript).StopPolling() + CWs.ResolveOffscreen(GetCurrentAttackDelta()) + + EndIf + +EndFunction diff --git a/source/scripts/cwcatapultoffscreenfirecontrolscript.psc b/source/scripts/cwcatapultoffscreenfirecontrolscript.psc new file mode 100644 index 00000000..0715ce3a --- /dev/null +++ b/source/scripts/cwcatapultoffscreenfirecontrolscript.psc @@ -0,0 +1,82 @@ +Scriptname CWCatapultOffscreenFireControlScript extends ObjectReference +{Controls the offscreen firing scripting. Set properties on the CWCatapultScript.} + +;Constants +string OffScreenFireModeOff = "OffScreenFireModeOff" +string OffScreenFireModeWaitingToFire = "OffScreenFireModeWaitingToFire" +string OffScreenFireModeBusyFiring = "OffScreenFireModeBusyFiring" + + +auto state OffScreenFireModeOff + Event OnUpdate() +; CWScript.Log("CWCatapultOffscreenFireControlScript", self + "OffScreenFireModeOff OnUpdate() doing nothing.") + EndEvent +EndState + +state OffScreenFireModeBusyFiring + Event OnUpdate() +; CWScript.Log("CWCatapultOffscreenFireControlScript", self + "OffScreenFireModeBusyFiring OnUpdate() doing nothing.") + EndEvent +EndState + +state OffScreenFireModeWaitingToFire + Event OnUpdate() + GoToState(OffScreenFireModeBusyFiring) + UnregisterForUpdate() + + + CWCatapultScript Cs = (self as ObjectReference) as CWCatapultScript + +; CWScript.Log("CWCatapultOffscreenFireControlScript", self + "OffScreenFireModeWaitingToFire OnUpdate() going to state OffScreenFireModeBusyFiring and possibly firing strike if in correct phase ") + + if Cs.UseCWCatapultStrikeSpawners == True + if Cs.UseCWCatapultStrikeSpawners == True ;in case we turned that off during the wait + if Cs.CWBattlePhase.GetValue() == 0 && GetLinkedRef(Cs.CW1) +; CWScript.Log("CWCatapultOffscreenFireControlScript", self + "startSpawningCatapultStrikes() Calling CallCatapultStrike() on " + GetLinkedRef(Cs.CW1)) + (GetLinkedRef(Cs.CW1) as CWCatapultStrikeSpawnerScript).CallCatapultStrike() + elseif Cs.CWBattlePhase.GetValue() == 1 && GetLinkedRef(Cs.CW1) +; CWScript.Log("CWCatapultOffscreenFireControlScript", self + "startSpawningCatapultStrikes() Calling CallCatapultStrike() on " + GetLinkedRef(Cs.CW1)) + (GetLinkedRef(Cs.CW1) as CWCatapultStrikeSpawnerScript).CallCatapultStrike() + elseif Cs.CWBattlePhase.GetValue() == 2 && GetLinkedRef(Cs.CW2) +; CWScript.Log("CWCatapultOffscreenFireControlScript", self + "startSpawningCatapultStrikes() Calling CallCatapultStrike() on " + GetLinkedRef(Cs.CW2)) + (GetLinkedRef(Cs.CW2) as CWCatapultStrikeSpawnerScript).CallCatapultStrike() + elseif Cs.CWBattlePhase.GetValue() == 3 && GetLinkedRef(Cs.CW3) +; CWScript.Log("CWCatapultOffscreenFireControlScript", self + "startSpawningCatapultStrikes() Calling CallCatapultStrike() on " + GetLinkedRef(Cs.CW3)) + (GetLinkedRef(Cs.CW3) as CWCatapultStrikeSpawnerScript).CallCatapultStrike() + elseif Cs.CWBattlePhase.GetValue() == 4 && GetLinkedRef(Cs.CW4) +; CWScript.Log("CWCatapultOffscreenFireControlScript", self + "startSpawningCatapultStrikes() Calling CallCatapultStrike() on " + GetLinkedRef(Cs.CW4)) + (GetLinkedRef(Cs.CW4) as CWCatapultStrikeSpawnerScript).CallCatapultStrike() + elseif Cs.CWBattlePhase.GetValue() == 5 && GetLinkedRef(Cs.CW5) +; CWScript.Log("CWCatapultOffscreenFireControlScript", self + "startSpawningCatapultStrikes() Calling CallCatapultStrike() on " + GetLinkedRef(Cs.CW5)) + (GetLinkedRef(Cs.CW5) as CWCatapultStrikeSpawnerScript).CallCatapultStrike() + elseif GetLinkedRef(Cs.CWAllPhases) +; CWScript.Log("CWCatapultOffscreenFireControlScript", self + "startSpawningCatapultStrikes() Calling CallCatapultStrike() on " + GetLinkedRef(Cs.CWAllPhases)) + (GetLinkedRef(Cs.CWAllPhases) as CWCatapultStrikeSpawnerScript).CallCatapultStrike() + + Else +; CWScript.Log("CWCatapultOffscreenFireControlScript", self + "startSpawningCatapultStrikes() NOT calling CallCatapultStrike() because CWBattlePhase == x which doesn't match a GetLinkedRef CWx", 1) + EndIf + + GoToState(OffScreenFireModeWaitingToFire) + RegisterForUpdate(Cs.GetTimeToNextLaunch()) + + EndIf + + EndIf + + EndEvent + +EndState + + +function StopOffscreenFiring() + GoToState(OffScreenFireModeOff) +; CWScript.Log("CWCatapultOffscreenFireControlScript", self + "StopOffscreenFiring() so went to state OffscreenFireModeOff, calling UnRegisterForUpdate()") + UnregisterForUpdate() +EndFunction + +function StartOffscreenFiring(float LaunchTime) + GoToState(OffScreenFireModeWaitingToFire) + RegisterForUpdate(LaunchTime) +; CWScript.Log("CWCatapultOffscreenFireControlScript", self + "StartOffscreenFiring() so went to state OffScreenFireModeWaitingToFire") +EndFunction diff --git a/source/scripts/cwcatapultscript.psc b/source/scripts/cwcatapultscript.psc new file mode 100644 index 00000000..884fcfce --- /dev/null +++ b/source/scripts/cwcatapultscript.psc @@ -0,0 +1,399 @@ +Scriptname CWCatapultScript extends ObjectReference +{Script on the CWCatapult Activator} + +;NOTES: + +;NORMAL OPERATION: +;To start catapults, 1) Enable() them, THEN 2) call TurnOn() -- THE ORDER IS IMPORTANT... ENABLE() FIRST if you don't then you put it in the mode to always fire as if it were "offscreen" and unloaded +;To stop catapults, 1) call the turnOff() function, then 2) Disable() them -- THE ORDER IS IMPORTANT +;When it's appropriate and you want to start using the CWCatapultStrikeSpawners to pin point where each hit should land, disable() the catapult which will cause it to start using the special effects instead of practical projectiles. + +;When the catapult unloads it sets the UseCWCatapultStrikeSpawners bool to true and calls startSpawningCatapultStrikes() which based on the CWBattlePhase will place special fx explosions at linked refs linked with keywords CW1, CW2, CW3, CW4, CW5 based on the phase + +;START DISABLED AND FIRE USING SPECIAL EFFECTS ONLY: +;To make a catapult never appear in the world but still fire with the special fx explosions, make sure it starts disabled, and instead of enable() it, just call turnOn() function on it. It assumes if it's disabled and you call turnOn() it should start firing as if it was unloaded + + +;AIMING THE CATAPULT +;Run the game, and "setpv aim True" on it in the console +;Now when you activate it in the ready position, it will pop up an aim menu +;One of the options is "Log Coordinates" this will print out the x, y, z position and angles to a text file so you can then enter those in the editor +;One special option is the "Face Target" button. By default this is the player, so you can run to where you want it to aim towards and then activate it via console (prid it, then "activate player") and it will face toward you +;you can also set this as a property on the reference if you have another reference you want to aim it at +;DON'T FORGET to push the "Log Coordinates" button on each catapult you aim, or you will have lost your targetting data + + +Weapon Property WeaponToFire Auto +{BASEOBJECT: Set this to CWCatapultWeapon, this is the weapon that the fire() function is called on.} + +Ammo Property AmmoToFire Auto +{BASEOBJECT: Set this to CWCatapultAmmo, this is the ammo parameter that the fire() function is passed.} + +GlobalVariable Property CWBattlePhase Auto +{BASEOBJECT: Pointer to CWBattlePhase global} + +keyword Property CW1 Auto +{BASEOBJET: pointer to keyword CW1 which defines the CWCatapultStrikerSpawner associated with phase 1 that should place catapult strike effects if this catapult is unloaded and CWBattlePhase is the correct phase} + +keyword Property CW2 Auto +{BASEOBJET: pointer to keyword CW2 which defines the CWCatapultStrikerSpawner associated with phase 2 that should place catapult strike effects if this catapult is unloaded and CWBattlePhase is the correct phase} + +keyword Property CW3 Auto +{BASEOBJET: pointer to keyword CW3 which defines the CWCatapultStrikerSpawner associated with phase 3 that should place catapult strike effects if this catapult is unloaded and CWBattlePhase is the correct phase} + +keyword Property CW4 Auto +{BASEOBJET: pointer to keyword CW4 which defines the CWCatapultStrikerSpawner associated with phase 4 that should place catapult strike effects if this catapult is unloaded and CWBattlePhase is the correct phase} + +keyword Property CW5 Auto +{BASEOBJET: pointer to keyword CW5 which defines the CWCatapultStrikerSpawner associated with phase 5 that should place catapult strike effects if this catapult is unloaded and CWBattlePhase is the correct phase} + +keyword Property CWAllPhases Auto +{BASEOBJET: pointer to keyword CWAllPhases which defines the CWCatapultStrikerSpawner associated with all phases that should place catapult strike effects if this catapult is unloaded} + +Message Property CWCatapultMsgAngle Auto +{BASEOBJECT: pointer to the CWCatapultMsgAngle message} + +Message Property CWCatapultMsgPosition Auto +{BASEOBJECT: pointer to the CWCatapultMsgAngle message} + +float property MinStrikeSpawnerTime = 5.0 Auto +{Optional REFERENCE: minimum seconds that should pass between each CWCatapultStrike special effect Explosion from this catapult} + +float property MaxStrikeSpawnerTime = 10.0 Auto +{Optional REFERENCE: maximum seconds that should pass between each CWCatapultStrike special effect Explosion from this catapult} + +Bool Property Aim Auto +{DEBUG: Put the catapult in aiming mode.} + +ObjectReference Property FaceTarget auto +{DEBUG: object ref id aim at, set before activating the Aiming mode menu in game} + + + + + +;Private Properties / Variables +bool property UseCWCatapultStrikeSpawners auto ;when this is true, don't launch normally, but instead call in special effect explosions (this is set to true when the object is unloaded) +{DON'T SET THIS, FOR DEBUGGING AND INTERNAL USE BY SCRIPT ONLY} + +;set bu TurnOn() and TurnOff() +bool Property TurnedOn Auto ;*** WHEN WE ARE DONE SETTING UP THIS SHOULD BE OFF BY DEFAILT AND TURNED ON WITH A FUNCTION +{DON'T SET THIS, FOR DEBUGGING AND INTERNAL USE BY SCRIPT ONLY} + +; +;state names - must be the same as the name of the states +string busy = "busy" ;busy animating +string ready = "ready" ;loaded and ready to fire +string fired = "fired" ;fired Projectile + + + +;animation events - for convenience these are declared as string variables +string aeFire = "fire" ;send this event to cause the catapult arm to fly up and launch the payload +string aeLaunch = "launch" ;[OBSOLETE] sent from activator at the moment the payload leaves the arm - this is when the weapon should call fire() +string aeFired = "fired" ;sent from activator when the launch animation is complete and it's safe to allow activate events to load it again +string aeReload = "reload" ;send this event to cause the catapult arm to lower and spawn a new payload +string aeReloaded = "reloaded" ;sent from activator when the reload animation is finished and it's safe to allow activate events to launch it again + +string aeStartFired = "startFired" ;send to activator to start a catapult in the fired position. Do not call this any other time than OnLoad or it will look bad. +; + +Event OnLoad() + + + ((self as ObjectReference) as CWCatapultOffscreenFireControlScript).StopOffscreenFiring() + UseCWCatapultStrikeSpawners = False + +; CWScript.Log("CWCatapultScript", self + "OnLoad()") + + RegisterForAnimationEvent(self, aeFire) ;arm goes up and payload launces + RegisterForAnimationEvent(self, aeLaunch) ;last few frames as the payload launches - should coincide with the fire() function call + RegisterForAnimationEvent(self, aeFired) ;arm is at rest after finished launching + RegisterForAnimationEvent(self, aeReload) ;arm goes down and payload appears in it + RegisterForAnimationEvent(self, aeReloaded) ;arm is down and payload appeared + RegisterForAnimationEvent(self, aeStartFired) ;arm should start up + +endEvent + +Event OnUnload() + + if UseCWCatapultStrikeSpawners == False && TurnedOn == true ;if we aren't already doing this for some reason, go ahead and Start + startSpawningCatapultStrikes() + EndIf + +; debug.MessageBox(self + "OnUnload()") +; CWScript.Log("CWCatapultScript", self + "OnUnload()") + + UnRegisterForAnimationEvent(self, aeFire) + UnRegisterForAnimationEvent(self, aeLaunch) + UnRegisterForAnimationEvent(self, aeFired) + UnRegisterForAnimationEvent(self, aeReload) + UnRegisterForAnimationEvent(self, aeReloaded) + UnRegisterForAnimationEvent(self, aeStartFired) +endEvent + +state busy + Event OnBeginState() +; CWScript.Log("CWCatapultScript", self + "OnBeginState() busy") + EndEvent + + ;catch activate + Event OnActivate(ObjectReference akActionRef) +; CWScript.Log("CWCatapultScript", self + "OnActivate(" + akActionRef + "): busy, so doing nothing.") + EndEvent + + +EndState + +auto state ready + Event OnBeginState() +; CWScript.Log("CWCatapultScript", self + "OnBeginState() ready") + EndEvent + + ;catch activate + Event OnActivate(ObjectReference akActionRef) + + if aim == true + showAimingMenu() + Else + + if UseCWCatapultStrikeSpawners == False + launch() +; CWScript.Log("CWCatapultScript", self + "OnActivate(" + akActionRef + ") ready, so called launch().") + + Else +; CWScript.Log("CWCatapultScript", self + "OnActivate(" + akActionRef + ") UseCWCatapultStrikeSpawners == True so I am not launching normally but calling in SFX catapult explosions.") + + EndIf + EndIf + + EndEvent + + +EndState + +state fired + Event OnBeginState() +; CWScript.Log("CWCatapultScript", self + "OnBeginState() fired") + EndEvent + + ;catch activate + Event OnActivate(ObjectReference akActionRef) + reload() +; CWScript.Log("CWCatapultScript", self + "OnActivate(" + akActionRef + ") fired, so called reload.") + EndEvent + +EndState + + +Event OnAnimationEvent(ObjectReference akSource, string asEventName) +; CWScript.Log("CWCatapultScript", self + "ProcessAnimationEvent(" + asEventName + ")") + if asEventName == aeReloaded + GoToState(ready) + + elseif asEventName == aeFired + GoToState(fired) + + endif +EndEvent + + +function TurnOn() + ;allowed to fire + TurnedOn = True + +;*** PUT THIS BACK IN WHEN WE HAVE ACTORS LAUNCHING ENABLED CATAPULTS +; if IsDisabled() + startSpawningCatapultStrikes() +; EndIf +EndFunction + + +function TurnOff(bool AndDisable = True) + ;not allowed to fire + TurnedOn = False + + if AndDisable == True + disable() + EndIf + + ((self as ObjectReference) as CWCatapultOffscreenFireControlScript).StopOffscreenFiring() + +EndFunction + +float function GetTimeToNextLaunch() + float timeToNextLaunch = Utility.RandomFloat(MinStrikeSpawnerTime, MaxStrikeSpawnerTime) +; CWScript.Log("CWCatapultScript", self + "GetTimeToNextLaunch() returning " + timeToNextLaunch) + Return timeToNextLaunch +EndFunction + + +function startSpawningCatapultStrikes() + + if TurnedOn == False +; CWScript.Log("GetTimeToNextLaunch", self + "WARNING: my TurnedOn variable is false, I should NOT be calling startSpawningCatapultStrikes on myself.", 2, 1, 1) + + Else + + UseCWCatapultStrikeSpawners = True + ((self as ObjectReference) as CWCatapultOffscreenFireControlScript).StartOffscreenFiring(GetTimeToNextLaunch()) + + EndIf + +EndFunction + +function launch() + GoToState(busy) +; CWScript.Log("CWCatapultScript", self + "launch()") + PlayAnimationAndWait(aeFire, aeLaunch) + + WeaponToFire.fire(self, AmmoToFire) + +EndFunction + +function reload() + GoToState(busy) +; CWScript.Log("CWCatapultScript", self + "reload()") + PlayAnimation(aeReload) + +EndFunction + + + + +;AIMING MENU STUFF + + +function showAimingMenu() + + float translateSpeed = 100 + + Message thisMessage = CWCatapultMsgAngle + + int button = thisMessage.Show() + int left = 0 + int right = 1 + int back = 2 + int forward = 3 + int face = 4 + int nextMenu = 5 + int log = 6 + int done = 7 + + + float offset = 1 + + if button == left + translateTo(X, Y, Z, GetAngleX(), GetAngleY(), GetAngleZ() - offset, translateSpeed) + elseif button == right + translateTo(X, Y, Z, GetAngleX(), GetAngleY(), GetAngleZ() + offset, translateSpeed) + elseif button == back + translateTo(X, Y, Z, GetAngleX(), GetAngleY() - offset, GetAngleZ(), translateSpeed) + elseif button == forward + translateTo(X, Y, Z, GetAngleX(), GetAngleY() + offset, GetAngleZ(), translateSpeed) + elseif button == face + translateTo(X, Y, Z, GetAngleX(), GetAngleY(), GetFacingToTarget(FaceTarget, True), translateSpeed) + elseif button == nextMenu + showPositioningMenu() + elseif button == log + logPositionAndAngle() + EndIf + + if button != done + showAimingMenu() + EndIf + +EndFunction + + +function showPositioningMenu() + + float translateSpeed = 100 + + Message thisMessage = CWCatapultMsgPosition + + int button = thisMessage.Show() + int left = 0 + int right = 1 + int back = 2 + int forward = 3 + int up = 4 + int down = 5 + int nextMenu = 6 + int log = 7 + int done = 8 + + + float offset = 1 + + float xOffset + float yOffset + + + + ;NOTE: the catapult art is setup facing backwards which is why when moving left/back we add the offsets and moving right/forward we subtract the offsets + + if button == left + xOffset = offset * math.cos(GetAngleZ()) + yOffset = offset * -( math.sin(GetAngleZ()) ) + translateTo(X + xOffset, Y + yOffset, Z, GetAngleX(), GetAngleY(), GetAngleZ(), translateSpeed) + + elseif button == right + xOffset = offset * math.cos(GetAngleZ()) + yOffset = offset * -( math.sin(GetAngleZ()) ) + translateTo(X - xOffset, Y - yOffset, Z, GetAngleX(), GetAngleY(), GetAngleZ(), translateSpeed) + + elseif button == back + xOffset = offset * math.sin(GetAngleZ()) + yOffset = offset * math.cos(GetAngleZ()) + translateTo(X + xOffset, Y + yOffset, Z, GetAngleX(), GetAngleY(), GetAngleZ(), translateSpeed) + + elseif button == forward + xOffset = offset * math.sin(GetAngleZ()) + yOffset = offset * math.cos(GetAngleZ()) + translateTo(X - xOffset, Y - yOffset, Z, GetAngleX(), GetAngleY(), GetAngleZ(), translateSpeed) + + elseif button == up + translateTo(X, Y, Z + offset, GetAngleX(), GetAngleY(), GetAngleZ(), translateSpeed) + elseif button == down + translateTo(X, Y, Z - offset, GetAngleX(), GetAngleY(), GetAngleZ(), translateSpeed) + elseif button == nextMenu + showAimingMenu() + elseif button == log + LogPositionAndAngle() + EndIf + + + if button != done + showPositioningMenu() + EndIf + +EndFunction + +function LogPositionAndAngle() +; CWScript.Log("CWCatapultAimingLog", self + "X: " + X + ", Y:" + Y + ", Z:" + Z + ", Angle X:" + GetAngleX() + ", Angle Y:" + GetAngleY() + ", Angle Z:" + GetAngleZ(), 1, 1) + +EndFunction + + +float function GetFacingToTarget(ObjectReference TargetRef, bool invertFacing = False) + + float deltaX = TargetRef.X - X + float deltaY = TargetRef.Y - Y + float newAngle = math.atan(deltaX/deltaY) + + if TargetRef.Y < Y + newAngle += 180 + EndIf + + if invertFacing + if newAngle >= 180 + newAngle -= 180 + Else + newAngle += 180 + EndIf + EndIf + + return newAngle +EndFunction + diff --git a/source/scripts/cwcatapultstrikescript.psc b/source/scripts/cwcatapultstrikescript.psc new file mode 100644 index 00000000..5e57dd94 --- /dev/null +++ b/source/scripts/cwcatapultstrikescript.psc @@ -0,0 +1,53 @@ +Scriptname CWCatapultStrikeScript extends ObjectReference + +;This script handles the "fallout 3 artillary" style catapult strike for use when the actual projectile firing catapults unload. + + +Explosion Property ExplosionObject Auto +{BASEOBJECT: the explosion to use -> CWCatapultExp} + +int deleteAfterTime = 10 +bool dead = false ; If true, then we are dead and we shouldn't try to register for stuff + +Event OnInit() + Cell parentCell = GetParentCell() + if !parentCell || !parentCell.IsAttached() + dead = true + Delete() + EndIf +EndEvent + +Event OnLoad() + if !dead + bool Registered = RegisterForAnimationEvent(self, "end") +; debug.trace(self + "OnLoad() successfully registered for event?:" + Registered) + + RegisterForSingleUpdate(deleteAfterTime) + EndIf +EndEvent + +Event OnAnimationEvent(ObjectReference akSource, string asEventName) +; debug.trace(self + "OnAnimationEvent(:" + asEventName ) + + if asEventName == "end" + PlaceAtMe(ExplosionObject) + UnregisterForAnimationEvent(self, "end") + deleteMe() + EndIf +EndEvent + +Event OnUpdate() + deleteMe() +EndEvent + +Event OnAnimationEventUnregistered(ObjectReference akSource, string asEventName) + deleteMe() +EndEvent + +Event deleteMe() + dead = true + UnregisterforUpdate() + UnregisterForAnimationEvent(self, "end") + Disable() + Delete() +EndEvent diff --git a/source/scripts/cwreinforcementcontrollerscript.psc b/source/scripts/cwreinforcementcontrollerscript.psc new file mode 100644 index 00000000..09721b67 --- /dev/null +++ b/source/scripts/cwreinforcementcontrollerscript.psc @@ -0,0 +1,1328 @@ +Scriptname CWReinforcementControllerScript extends Quest + +int Property ReinforcementInterval = 5 Auto +{Waves respawn every X seconds, default = 5} + +float Property PoolAttacker auto hidden ;the current reinforcement pool value +float Property PoolDefender auto hidden ;the current reinforcement pool value + +float Property StartingPoolAttacker auto Hidden +float Property StartingPoolDefender auto Hidden + +bool Property InfiniteRespawnAttacker auto Hidden ;don't subtract from pools, always treat checks for cost to respawn as passing +bool Property InfiniteRespawnDefender auto Hidden ;don't subtract from pools, always treat checks for cost to respawn as passing + + +int Property ThresholdCounterPoolAttacker = -999 auto Hidden ;chunk of reinforcements left, when increments, it means it's time to show objective to player -- for example, every 5% change in pool, increment this value and show the pools to the player +int Property ThresholdCounterPoolDefender = -999 auto Hidden ;chunk of reinforcements left, when increments, it means it's time to show objective to player -- for example, every 5% change in pool, increment this value and show the pools to the player + +int Property PostTicketAttackerCountThreshold = 5 Auto +{Default = 5. After attacker has run out of tickets, how many living attackers should be left before setting the stage defined in StageToSetIfAttackerWipedOut} + +int Property PostTicketDefenderCountThreshold = 5 Auto +{Default = 5. After defender has run out of tickets, how many living attackers should be left before setting the stage defined in StageToSetIfDefenderWipedOut} + +int Property StageToSetIfAttackerWipedOut Auto +{What stage to set if attacker is out of tickets and the number of living attackers is <= to PostTicketAttackerCountThreshold} + +int Property StageToSetIfDefenderWipedOut Auto +{What stage to set if attacker is out of tickets and the number of living attackers is <= to PostTicketDefenderCountThreshold} + +int Property StageToSetIfAttacker25PercentRemainging Auto +{What stage to set if attacker has 25% reinforcements remaining} + +int Property StageToSetIfDefender25PercentRemainging Auto +{What stage to set if attacker has 25% reinforcements remaining} + +bool Property ShowAttackerPoolObjective Auto +{Will we be turning on an objective to show how many attackers are remaining (used for defense sieges} + +bool Property ShowDefenderPoolObjective Auto +{Will we be turning on an objective to show how many attackers are remaining (used for defense sieges} + +Quest Property PoolRemainingObjectiveQuest Auto +{Which quest holds the objective for attacker/defender losses} + +int Property PoolRemainingAttackerObjective Auto +{Which objective to set in LossesQuest to show Attacker losses} + +int Property PoolRemainingDefenderObjective Auto +{Which objective to set in LossesQuest to show Defender losses} + + +Int costForReinforcement = 1 + +bool iterating ;are we in the middle of iterating through the "array" respawning guys? +bool iterateAgain ;should we iterate again through the array immediately? (if someone dies while currently iterating, we should iterate again just to make sure we catch him) + +;Spawn Points +ObjectReference Property SpawnAttacker1 auto hidden +ObjectReference Property SpawnAttacker2 auto hidden +ObjectReference Property SpawnAttacker3 auto hidden +ObjectReference Property SpawnAttacker4 auto hidden +ObjectReference Property SpawnAttackerFailSafe auto hidden + +ObjectReference Property SpawnDefender1 auto hidden +ObjectReference Property SpawnDefender2 auto hidden +ObjectReference Property SpawnDefender3 auto hidden +ObjectReference Property SpawnDefender4 auto hidden +ObjectReference Property SpawnDefenderFailSafe auto hidden + +;Attacker Reinforcements "array" +ReferenceAlias A1 +ReferenceAlias A2 +ReferenceAlias A3 +ReferenceAlias A4 +ReferenceAlias A5 +ReferenceAlias A6 +ReferenceAlias A7 +ReferenceAlias A8 +ReferenceAlias A9 +ReferenceAlias A10 +ReferenceAlias A11 +ReferenceAlias A12 +ReferenceAlias A13 +ReferenceAlias A14 +ReferenceAlias A15 +ReferenceAlias A16 +ReferenceAlias A17 +ReferenceAlias A18 +ReferenceAlias A19 +ReferenceAlias A20 + +;Defender Reinforcements "array" +ReferenceAlias D1 +ReferenceAlias D2 +ReferenceAlias D3 +ReferenceAlias D4 +ReferenceAlias D5 +ReferenceAlias D6 +ReferenceAlias D7 +ReferenceAlias D8 +ReferenceAlias D9 +ReferenceAlias D10 +ReferenceAlias D11 +ReferenceAlias D12 +ReferenceAlias D13 +ReferenceAlias D14 +ReferenceAlias D15 +ReferenceAlias D16 +ReferenceAlias D17 +ReferenceAlias D18 +ReferenceAlias D19 +ReferenceAlias D20 + +;#ALIAS HOLDING THE ATTACK POINT LOCATION +Location AttackPoint + + +;## Quests ## +Quest Property CW auto +Quest Property CWCampaign auto + +;## Scripts ## +CWCampaignScript Property CWCampaignS auto Hidden ;set in OnInit() +CWscript Property CWs auto Hidden ;set in OnInit() + + + +Event OnInit() + + CWCampaignS = CWCampaign as CWCampaignScript + CWs = CW as CWscript + +; CWScript.Log("CWReinforcementControllerScript", self + "OnInit()", 0, true, true) + +EndEvent + + +;State StopSpawning -- no longer try to respawn +State StopSpawning + + Function registerDeath(ReferenceAlias DeadAlias) + ;Do nothing + +; CWScript.Log("CWReinforcementControllerScript", self + "registerDeath(" + DeadAlias + ") [in state 'StopSpawning'] so will do nothing.") + EndFunction +EndState + + +; STATE RESPAWNING +State Respawning + + Function registerDeath(ReferenceAlias DeadAlias) ;called in OnDeath event of the dying actor/ReferenceAlias + + + if iterating == True +; CWScript.Log("CWReinforcementControllerScript", self + "registerDeath(" + DeadAlias + ") [in state 'Respawning'] and currently iterating through 'array' respawning, so set flag that means iterate again immediately so we pick up this guy if we've already passed his positionin the array.") + iterateAgain = True + + Else +; CWScript.Log("CWReinforcementControllerScript", self + "registerDeath(" + DeadAlias + ") [in state 'Respawning'] and not currently iterating through 'array' respawning, so doing nothing") + EndIf + + + EndFunction + +EndState +; /STATE RESPAWNING + +function StopSpawning() + GoToState("StopSpawning") + +; CWScript.Log("CWReinforcementControllerScript", self + "stopSpawning() called - went to state 'StopSpawning'") +EndFunction + +function registerDeath(ReferenceAlias DeadAlias) ;called in OnDeath event of the dying actor/ReferenceAlias + GoToState("Respawning") + + +; CWScript.Log("CWReinforcementControllerScript", self + "registerDeath(" + DeadAlias + ") [in state 'none'] gone to state 'Respawning'") + + bool done = False + +; CWScript.Log("CWReinforcementControllerScript", self + "registerDeath(" + DeadAlias + ") [in state 'none'] will now Wait(" + ReinforcementInterval + ") to spawn reinforcements") + + utility.Wait(ReinforcementInterval) + +; CWScript.Log("CWReinforcementControllerScript", self + "registerDeath(" + DeadAlias + ") [in state 'none'] is done waiting and will now try to respawn Aliass") + + + + while !done || iterateAgain ;iterateAgain is set in RegisterDeath() function in the "Respawning" state above + iterating = True ;see RegisterDeath() function in the "Respawning" state above + iterateAgain = False + + tryToRespawnAliass() + + done = True + + iterating = False ;see RegisterDeath() function in the "Respawning" state above + endwhile + + if GetState() != "StopSpawning" ;reminder case sensative + GoToState("none") +; CWScript.Log("CWReinforcementControllerScript", self + "registerDeath() [in state 'none'] is done respawning and is gone to state 'none'") + EndIf + + + +EndFunction + +function tryToRespawnAliass() + + shuffleSpawnMarkers() + + ;CALL TryToRespawnAlias for each variable in both arrays + TryToRespawnAlias(A1) + TryToRespawnAlias(A2) + TryToRespawnAlias(A3) + TryToRespawnAlias(A4) + TryToRespawnAlias(A5) + TryToRespawnAlias(A6) + TryToRespawnAlias(A7) + TryToRespawnAlias(A8) + TryToRespawnAlias(A9) + TryToRespawnAlias(A10) + TryToRespawnAlias(A11) + TryToRespawnAlias(A12) + TryToRespawnAlias(A13) + TryToRespawnAlias(A14) + TryToRespawnAlias(A15) + TryToRespawnAlias(A16) + TryToRespawnAlias(A17) + TryToRespawnAlias(A18) + TryToRespawnAlias(A19) + TryToRespawnAlias(A20) + + TryToRespawnAlias(D1) + TryToRespawnAlias(D2) + TryToRespawnAlias(D3) + TryToRespawnAlias(D4) + TryToRespawnAlias(D5) + TryToRespawnAlias(D6) + TryToRespawnAlias(D7) + TryToRespawnAlias(D8) + TryToRespawnAlias(D9) + TryToRespawnAlias(D10) + TryToRespawnAlias(D11) + TryToRespawnAlias(D12) + TryToRespawnAlias(D13) + TryToRespawnAlias(D14) + TryToRespawnAlias(D15) + TryToRespawnAlias(D16) + TryToRespawnAlias(D17) + TryToRespawnAlias(D18) + TryToRespawnAlias(D19) + TryToRespawnAlias(D20) + + +EndFunction + + +Function TryToRespawnAlias(ReferenceAlias AliasToRespawn) + + float pool + bool isAttacker + + if !AliasToRespawn || AliasToRespawn.GetActorReference().IsDead() == False +; CWScript.Log("CWReinforcementControllerScript", self + "TryToRespawnAlias(" + AliasToRespawn + ") variable is empty or is currently alive, so we are returning without trying to repawn.") + + Return + EndIf + + ;Determine which pool to use, store in pool variable +; CWScript.Log("CWReinforcementControllerScript", self +"TryToRespawnAlias(" + AliasToRespawn + ") calling IsAliasAttacker()" ) + if IsAliasAttacker(AliasToRespawn) + isAttacker = true + EndIf + + + if IsAttacker +; CWScript.Log("CWReinforcementControllerScript", self +"TryToRespawnAlias(" + AliasToRespawn + ") is an Attacker. PoolAttacker == " + PoolAttacker ) + pool = PoolAttacker + + else ;assuming is Defender +; CWScript.Log("CWReinforcementControllerScript", self +"TryToRespawnAlias(" + AliasToRespawn + ") is not an Attacker (assuming is Defender). PoolDefender ==" + PoolDefender ) + pool = PoolDefender + + EndIf + + + ;CHECK FOR POOL NOT BEING EMPTY + if pool < costForReinforcement +; CWScript.Log("CWReinforcementControllerScript", self +"TryToRespawnAlias(" + AliasToRespawn + ")... Pool(" + pool + ") < costForReinforcement(" + costForReinforcement + ") So we won't respawn, and will check to see if all teammates are dead." ) + + ;CHECK FOR ALL THE VARIABLES BEING DEAD, IF THEY ARE, THEN SET THE STAGE + if isAttacker +; CWScript.Log("CWReinforcementControllerScript", self +"TryToRespawnAlias(" + AliasToRespawn + ") is an Attacker, checking CountAttackersAlive()" ) + + if GetStageDone(StageToSetIfAttackerWipedOut) == True +; CWScript.Log("CWReinforcementControllerScript", self +"TryToRespawnAlias(" + AliasToRespawn + ") StageToSetIfAttackerWipedOut[" + StageToSetIfAttackerWipedOut + "] is set, not bothering to check if any are alive." ) + + Else + if CountAttackersAlive() > PostTicketAttackerCountThreshold +; CWScript.Log("CWReinforcementControllerScript", self +"CountAttackersAlive() > PostTicketAttackerCountThreshold[" + PostTicketAttackerCountThreshold + "] so doing nothing." ) + Else +; CWScript.Log("CWReinforcementControllerScript", self +"CountAttackersAlive() <= PostTicketAttackerCountThreshold[" + PostTicketAttackerCountThreshold + "], so we are setting stage that means all the Attackers are wiped out: " + StageToSetIfAttackerWipedOut) + + if ShowAttackerPoolObjective + showAttackerPool() + endif + + setStage(StageToSetIfAttackerWipedOut) + + EndIf + + endif + + + else ;assuming is Defender +; CWScript.Log("CWReinforcementControllerScript", self +"TryToRespawnAlias(" + AliasToRespawn + ") is a Defender, checking CountDefendersAlive()" ) + + if GetStageDone(StageToSetIfDefenderWipedOut) == True +; CWScript.Log("CWReinforcementControllerScript", self +"TryToRespawnAlias(" + AliasToRespawn + ") StageToSetIfDefenderWipedOut[" + StageToSetIfDefenderWipedOut + "] is set, not bothering to check if any are alive." ) + + Else + if CountDefendersAlive() > PostTicketDefenderCountThreshold +; CWScript.Log("CWReinforcementControllerScript", self +"CountDefendersAlive() > PostTicketDefenderCountThreshold[" + PostTicketDefenderCountThreshold + "] so doing nothing." ) + Else +; CWScript.Log("CWReinforcementControllerScript", self +"CountDefendersAlive() <= PostTicketDefenderCountThreshold[" + PostTicketDefenderCountThreshold + "], so we are setting stage that means all the Defenders are wiped out: " + StageToSetIfDefenderWipedOut) + + if ShowDefenderPoolObjective + showDefenderPool() + endif + + setStage(StageToSetIfDefenderWipedOut) + + EndIf + + EndIf + + EndIf + +; CWScript.Log("CWReinforcementControllerScript", self + "not respawning " + AliasToRespawn + " which is ref:" + AliasToRespawn.GetReference()) + + Else +; CWScript.Log("CWReinforcementControllerScript", self + "respawning" + AliasToRespawn + " which is ref:" + AliasToRespawn.GetReference()) + + ;SPAWN ALIASES HERE + if isAttacker + ;SPAWN ME AND SUBTRACT FROM POOLAttacker + AliasToRespawn.GetActorReference().Reset(GetAttackerSpawnRef(AliasToRespawn)) + +; ;****TEMP TEST A THEORY ABOUT WHY STUFF IS BROKEN: +; utility.wait(2) +; if AliasToRespawn.GetActorReference().IsDead() +; ; CWScript.Log("CWReinforcementControllerScript", self + " TEMP DEBUG WARNING: Just tried to respawn " + AliasToRespawn + AliasToRespawn.GetReference() + "and he's still dead!!!") +; Else +; ; CWScript.Log("CWReinforcementControllerScript", self + " TEMP DEBUG: All is well, just tried to respawn " + AliasToRespawn + AliasToRespawn.GetReference() + "and he's alive.") +; EndIf +; ;**** + + SubtractFromAttackerPool() + + else ;assuming is Defender + ;SPAWN ME AND SUBTRACT FROM POOLDefender + AliasToRespawn.GetActorReference().Reset(GetDefenderSpawnRef(AliasToRespawn)) + +; ;****TEMP TEST A THEORY ABOUT WHY STUFF IS BROKEN: +; utility.wait(2) +; if AliasToRespawn.GetActorReference().IsDead() +; ; CWScript.Log("CWReinforcementControllerScript", self + "TEMP DEBUG WARNING: Just tried to respawn " + AliasToRespawn + "and he's still dead!!!", 2, 1, 1) +; Else +; ; CWScript.Log("CWReinforcementControllerScript", self + "TEMP DEBUG: All is well, just tried to respawn " + AliasToRespawn + "and he's alive.", 1, 1, 1) +; EndIf +; ;**** + + SubtractFromDefenderPool() + + EndIf + + EndIf + +EndFunction + + +bool function IsAliasAttacker(ReferenceAlias AliasToRespawn) + + bool isAttacker + bool isDefender + + if AliasToRespawn.GetActorReference().IsInFaction(CWs.CWImperialFaction) + if CWs.iImperials == CWs.GetAttacker(AttackPoint) + isAttacker = true + Elseif CWs.iImperials == CWs.GetDefender(AttackPoint) + isDefender = true + Else +; CWScript.Log("CWReinforcementControllerScript", self + " ERROR: TryToRespawnAlias(" + AliasToRespawn + ") expected to be either the attacker, or the defender.", 2, True, True) + EndIf + + elseif AliasToRespawn.GetActorReference().IsInFaction(CWs.CWSonsFaction) + if CWs.iSons == CWs.GetAttacker(AttackPoint) + isAttacker = true + Elseif CWs.iSons == CWs.GetDefender(AttackPoint) + isDefender = true + Else +; CWScript.Log("CWReinforcementControllerScript", self + " ERROR: TryToRespawnAlias(" + AliasToRespawn + ") expected to be either the attacker, or the defender.", 2, True, True) + EndIf + + Else +; CWScript.Log("CWReinforcementControllerScript", self + " ERROR: TryToRespawnAlias(" + AliasToRespawn + ") expected to be either the Imperial faction or Sons faction, is neither.", 2, True, True) + + EndIf + + if isAttacker == True + return True + Else + return False + EndIf +EndFunction + + + +int Function CountAttackersAlive() + +; CWScript.Log("CWReinforcementControllerScript", self + "CountAttackersAlive() checking 'array' to see if all the actors are dead.") + + int returnVal + + returnVal += IsAliasAlive(A1) + returnVal += IsAliasAlive(A2) + returnVal += IsAliasAlive(A3) + returnVal += IsAliasAlive(A4) + returnVal += IsAliasAlive(A5) + returnVal += IsAliasAlive(A6) + returnVal += IsAliasAlive(A7) + returnVal += IsAliasAlive(A8) + returnVal += IsAliasAlive(A9) + returnVal += IsAliasAlive(A10) + returnVal += IsAliasAlive(A11) + returnVal += IsAliasAlive(A12) + returnVal += IsAliasAlive(A13) + returnVal += IsAliasAlive(A14) + returnVal += IsAliasAlive(A15) + returnVal += IsAliasAlive(A16) + returnVal += IsAliasAlive(A17) + returnVal += IsAliasAlive(A18) + returnVal += IsAliasAlive(A19) + returnVal += IsAliasAlive(A20) + +; CWScript.Log("CWReinforcementControllerScript", self + "CountAttackersAlive() will return:" + returnVal) + + return returnVal + +EndFunction + + + +int Function CountDefendersAlive() + +; CWScript.Log("CWReinforcementControllerScript", self + "CountDefendersAlive() checking 'array' to see if all the actors are dead.") + + int returnVal + + returnVal += IsAliasAlive(D1) + returnVal += IsAliasAlive(D2) + returnVal += IsAliasAlive(D3) + returnVal += IsAliasAlive(D4) + returnVal += IsAliasAlive(D5) + returnVal += IsAliasAlive(D6) + returnVal += IsAliasAlive(D7) + returnVal += IsAliasAlive(D8) + returnVal += IsAliasAlive(D9) + returnVal += IsAliasAlive(D10) + returnVal += IsAliasAlive(D11) + returnVal += IsAliasAlive(D12) + returnVal += IsAliasAlive(D13) + returnVal += IsAliasAlive(D14) + returnVal += IsAliasAlive(D15) + returnVal += IsAliasAlive(D16) + returnVal += IsAliasAlive(D17) + returnVal += IsAliasAlive(D18) + returnVal += IsAliasAlive(D19) + returnVal += IsAliasAlive(D20) + +; CWScript.Log("CWReinforcementControllerScript", self + "CountDefendersAlive() will return:" + returnVal) + + return returnVal + +EndFunction + +int Function IsAliasAlive(ReferenceAlias AliasVariableToCheck) + + + if AliasVariableToCheck && AliasVariableToCheck.GetActorReference().IsDead() == False +; CWScript.Log("CWReinforcementControllerScript", self + "IsAliasAlive() is returning true (1) for AliasVariableToCheck:" + AliasVariableToCheck) + Return 1 + + ElseIf AliasVariableToCheck && AliasVariableToCheck.GetActorReference().IsDead() == True +; CWScript.Log("CWReinforcementControllerScript", self + "IsAliasAlive() is returning false (0) for AliasVariableToCheck:" + AliasVariableToCheck) + return 0 + + Else +; CWScript.Log("CWReinforcementControllerScript", self + "IsAliasAlive() is returning false (0) for AliasVariableToCheck:" + AliasVariableToCheck + " because it's empty" ) + return 0 + + endif + +EndFunction + +Function RegisterAttackPoint(Location SiegeLocationAttackPoint) +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAttackPoint() setting AttackPoint to: " + SiegeLocationAttackPoint) + + AttackPoint = SiegeLocationAttackPoint +EndFunction + + +Function RegisterAlias(ReferenceAlias AliasToAdd) + +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAlias(" + AliasToAdd + ") checking faction and attacker or defender status, and then will call the appropriate RegisterAliasAttacker() or RegisterAliasDefender()") + + + + if AliasToAdd.GetActorReference().IsInFaction(CWs.CWImperialFaction) + if CWs.iImperials == CWs.GetAttacker(AttackPoint) + RegisterAliasAttacker(AliasToAdd) + Elseif CWs.iImperials == CWs.GetDefender(AttackPoint) + RegisterAliasDefender(AliasToAdd) + Else +; CWScript.Log("CWReinforcementControllerScript", self + " ERROR: FAILING TO ADD ReferenceAlias TO RESPAWN ARRAY! RegisterAlias(" + AliasToAdd + ") expected to be either the attacker, or the defender.", 2, True, True) + EndIf + + elseif AliasToAdd.GetActorReference().IsInFaction(CWs.CWSonsFaction) + if CWs.iSons == CWs.GetAttacker(AttackPoint) + RegisterAliasAttacker(AliasToAdd) + Elseif CWs.iSons == CWs.GetDefender(AttackPoint) + RegisterAliasDefender(AliasToAdd) + Else +; CWScript.Log("CWReinforcementControllerScript", self + " ERROR: FAILING TO ADD ReferenceAlias TO RESPAWN ARRAY! RegisterAlias(" + AliasToAdd + ") expected to be either the attacker, or the defender.", 2, True, True) + EndIf + + Else +; CWScript.Log("CWReinforcementControllerScript", self + " ERROR: RegisterAlias(" + AliasToAdd + ") expected to be either the Imperial faction or Sons faction, is neither.", 2, True, True) + + EndIf + +EndFunction + +Function RegisterAliasAttacker(ReferenceAlias AliasToAdd) + + + +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() is adding ReferenceAlias " + AliasToAdd) + + if !A1 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A1 variable") + A1 = AliasToAdd + elseif !A2 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A2 variable") + A2 = AliasToAdd + elseif !A3 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A3 variable") + A3 = AliasToAdd + elseif !A4 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A4 variable") + A4 = AliasToAdd + elseif !A5 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A5 variable") + A5 = AliasToAdd + elseif !A6 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A6 variable") + A6 = AliasToAdd + elseif !A7 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A7 variable") + A7 = AliasToAdd + elseif !A8 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A8 variable") + A8 = AliasToAdd + elseif !A9 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A9 variable") + A9 = AliasToAdd + elseif !A10 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A10 variable") + A10 = AliasToAdd + elseif !A11 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A11 variable") + A11 = AliasToAdd + elseif !A12 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A12 variable") + A12 = AliasToAdd + elseif !A13 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A13 variable") + A13 = AliasToAdd + elseif !A14 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A14 variable") + A14 = AliasToAdd + elseif !A15 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A15 variable") + A15 = AliasToAdd + elseif !A16 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A16 variable") + A16 = AliasToAdd + elseif !A17 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A17 variable") + A17 = AliasToAdd + elseif !A18 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A18 variable") + A18 = AliasToAdd + elseif !A19 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A19 variable") + A19 = AliasToAdd + elseif !A20 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasAttacker() adding ReferenceAlias to A20 variable") + A20 = AliasToAdd + Else + +; CWScript.Log("CWReinforcementControllerScript", self + " ERROR: RegisterAliasAttacker() ran out of 'array' variables; there is no variable to store ReferenceAlias", 2, True, True) + + EndIf +EndFunction + +Function RegisterAliasDefender(ReferenceAlias AliasToAdd) + + + +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() is adding ReferenceAlias " + AliasToAdd) + + if !D1 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D1 variable") + D1 = AliasToAdd + elseif !D2 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D2 variable") + D2 = AliasToAdd + elseif !D3 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D3 variable") + D3 = AliasToAdd + elseif !D4 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D4 variable") + D4 = AliasToAdd + elseif !D5 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D5 variable") + D5 = AliasToAdd + elseif !D6 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D6 variable") + D6 = AliasToAdd + elseif !D7 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D7 variable") + D7 = AliasToAdd + elseif !D8 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D8 variable") + D8 = AliasToAdd + elseif !D9 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D9 variable") + D9 = AliasToAdd + elseif !D10 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D10 variable") + D10 = AliasToAdd + elseif !D11 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D11 variable") + D11 = AliasToAdd + elseif !D12 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D12 variable") + D12 = AliasToAdd + elseif !D13 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D13 variable") + D13 = AliasToAdd + elseif !D14 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D14 variable") + D14 = AliasToAdd + elseif !D15 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D15 variable") + D15 = AliasToAdd + elseif !D16 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D16 variable") + D16 = AliasToAdd + elseif !D17 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D17 variable") + D17 = AliasToAdd + elseif !D18 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D18 variable") + D18 = AliasToAdd + elseif !D19 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D19 variable") + D19 = AliasToAdd + elseif !D20 +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterAliasDefender() adding ReferenceAlias to D20 variable") + D20 = AliasToAdd + Else + +; CWScript.Log("CWReinforcementControllerScript", self + " ERROR: RegisterAliasDefender() ran out of 'array' variables; there is no variable to store ReferenceAlias", 2, True, True) + + EndIf + +EndFunction + +ObjectReference Function TryToGetPrioritySpawnLinkedRef(ReferenceAlias AliasToCheckFor) + ;THIS IS VERY SIMILAR TO TryToGetForcedSpawnLinkedRef + +; CWScript.Log("CWReinforcementControllerScript", self + "TryToGetPrioritySpawnLinkedRef()" ) + + ObjectReference AliasRef = AliasToCheckFor.GetReference() + + ObjectReference linkedRefToReturn = None + + + if CWs.CWBattlePhase.Value == 1 && AliasRef.GetLinkedRef(CWs.CW1PrioritySpawn) + linkedRefToReturn = AliasRef.GetLinkedRef(CWs.CW1PrioritySpawn) +; CWScript.Log("CWReinforcementControllerScript", self + "TryToGetPrioritySpawnLinkedRef() found CW1PrioritySpawn link: " + linkedRefToReturn + " for: " + AliasRef ) + + elseif CWs.CWBattlePhase.Value == 2 && AliasRef.GetLinkedRef(CWs.CW2PrioritySpawn) + linkedRefToReturn = AliasRef.GetLinkedRef(CWs.CW2PrioritySpawn) +; CWScript.Log("CWReinforcementControllerScript", self + "TryToGetPrioritySpawnLinkedRef() found CW2PrioritySpawn link: " + linkedRefToReturn + " for: " + AliasRef ) + + elseif CWs.CWBattlePhase.Value == 3 && AliasRef.GetLinkedRef(CWs.CW3PrioritySpawn) + linkedRefToReturn = AliasRef.GetLinkedRef(CWs.CW3PrioritySpawn) +; CWScript.Log("CWReinforcementControllerScript", self + "TryToGetPrioritySpawnLinkedRef() found CW3PrioritySpawn link: " + linkedRefToReturn + " for: " + AliasRef ) + + elseif CWs.CWBattlePhase.Value == 4 && AliasRef.GetLinkedRef(CWs.CW4PrioritySpawn) + linkedRefToReturn = AliasRef.GetLinkedRef(CWs.CW4PrioritySpawn) +; CWScript.Log("CWReinforcementControllerScript", self + "TryToGetPrioritySpawnLinkedRef() found CW4PrioritySpawn link: " + linkedRefToReturn + " for: " + AliasRef ) + + elseif CWs.CWBattlePhase.Value == 5 && AliasRef.GetLinkedRef(CWs.CW5PrioritySpawn) + linkedRefToReturn = AliasRef.GetLinkedRef(CWs.CW5PrioritySpawn) +; CWScript.Log("CWReinforcementControllerScript", self + "TryToGetPrioritySpawnLinkedRef() found CW5PrioritySpawn link: " + linkedRefToReturn + " for: " + AliasRef ) + + Else +; CWScript.Log("CWReinforcementControllerScript", self + "TryToGetPrioritySpawnLinkedRef() didn't find an appropriate Priority Spawn Linked Ref for: " + AliasRef ) + + EndIf + + return linkedRefToReturn + +EndFunction + + +ObjectReference Function TryToGetForcedSpawnLinkedRef(ReferenceAlias AliasToCheckFor) + ;THIS IS VERY SIMILAR TO TryToGetPrioritySpawnLinkedRef + +; CWScript.Log("CWReinforcementControllerScript", self + "TryToGetForcedSpawnLinkedRef()" ) + + ObjectReference AliasRef = AliasToCheckFor.GetReference() + + ObjectReference linkedRefToReturn = None + + + if CWs.CWBattlePhase.Value == 1 && AliasRef.GetLinkedRef(CWs.CW1ForcedSpawn) + linkedRefToReturn = AliasRef.GetLinkedRef(CWs.CW1ForcedSpawn) +; CWScript.Log("CWReinforcementControllerScript", self + "TryToGetForcedSpawnLinkedRef() found CW1ForcedSpawn link: " + linkedRefToReturn + " for: " + AliasRef ) + + elseif CWs.CWBattlePhase.Value == 2 && AliasRef.GetLinkedRef(CWs.CW2ForcedSpawn) + linkedRefToReturn = AliasRef.GetLinkedRef(CWs.CW2ForcedSpawn) +; CWScript.Log("CWReinforcementControllerScript", self + "TryToGetForcedSpawnLinkedRef() found CW2ForcedSpawn link: " + linkedRefToReturn + " for: " + AliasRef ) + + elseif CWs.CWBattlePhase.Value == 3 && AliasRef.GetLinkedRef(CWs.CW3ForcedSpawn) + linkedRefToReturn = AliasRef.GetLinkedRef(CWs.CW3ForcedSpawn) +; CWScript.Log("CWReinforcementControllerScript", self + "TryToGetForcedSpawnLinkedRef() found CW3ForcedSpawn link: " + linkedRefToReturn + " for: " + AliasRef ) + + elseif CWs.CWBattlePhase.Value == 4 && AliasRef.GetLinkedRef(CWs.CW4ForcedSpawn) + linkedRefToReturn = AliasRef.GetLinkedRef(CWs.CW4ForcedSpawn) +; CWScript.Log("CWReinforcementControllerScript", self + "TryToGetForcedSpawnLinkedRef() found CW4ForcedSpawn link: " + linkedRefToReturn + " for: " + AliasRef ) + + elseif CWs.CWBattlePhase.Value == 5 && AliasRef.GetLinkedRef(CWs.CW5ForcedSpawn) + linkedRefToReturn = AliasRef.GetLinkedRef(CWs.CW5ForcedSpawn) +; CWScript.Log("CWReinforcementControllerScript", self + "TryToGetForcedSpawnLinkedRef() found CW5ForcedSpawn link: " + linkedRefToReturn + " for: " + AliasRef ) + + Else +; CWScript.Log("CWReinforcementControllerScript", self + "TryToGetForcedSpawnLinkedRef() didn't find an appropriate Forced Spawn Linked Ref for: " + AliasRef ) + + EndIf + + return linkedRefToReturn + +EndFunction + + + + + +ObjectReference Function GetAttackerSpawnRef(ReferenceAlias AliasToCheckFor) + ;VERY SIMILAR TO GetDefenderSpawnRef... these are different functions because I need to return attacker or defender spawn refs + + actor playerActor = Game.GetPlayer() as actor + +; CWScript.Log("CWReinforcementControllerScript", self + "GetAttackerSpawnRef() " ) + + ObjectReference PrioritySpawn = TryToGetPrioritySpawnLinkedRef(AliasToCheckFor) + ObjectReference ForcedSpawn = TryToGetForcedSpawnLinkedRef(AliasToCheckFor) + + if ForcedSpawn +; CWScript.Log("CWReinforcementControllerScript", self + "GetAttackerSpawnRef() playerActor.HasLOS(ForcedSpawn) == False, returning " + ForcedSpawn) + return ForcedSpawn + + Elseif PrioritySpawn && playerActor.HasLOS(PrioritySpawn) == False +; CWScript.Log("CWReinforcementControllerScript", self + "GetAttackerSpawnRef() playerActor.HasLOS(PrioritySpawn) == False, returning " + PrioritySpawn) + return PrioritySpawn + + elseif playerActor.HasLOS(SpawnAttacker1) == False +; CWScript.Log("CWReinforcementControllerScript", self + "GetAttackerSpawnRef() playerActor.HasLOS(SpawnAttacker1) == False, returning " + SpawnAttacker1) + return SpawnAttacker1 + + elseif playerActor.HasLOS(SpawnAttacker2) == False +; CWScript.Log("CWReinforcementControllerScript", self + "GetAttackerSpawnRef() playerActor.HasLOS(SpawnAttacker2) == False, returning " + SpawnAttacker2) + return SpawnAttacker2 + + elseif playerActor.HasLOS(SpawnAttacker3) == False +; CWScript.Log("CWReinforcementControllerScript", self + "GetAttackerSpawnRef() playerActor.HasLOS(SpawnAttacker3) == False, returning " + SpawnAttacker3) + return SpawnAttacker3 + + elseif playerActor.HasLOS(SpawnAttacker4) == False +; CWScript.Log("CWReinforcementControllerScript", self + "GetAttackerSpawnRef() playerActor.HasLOS(SpawnAttacker4) == False, returning " + SpawnAttacker4) + return SpawnAttacker4 + + else +; CWScript.Log("CWReinforcementControllerScript", self + "GetAttackerSpawnRef() playerActor.HasLOS to all the Spawn markers, returning the SpawnAttackerFailsafe:" + SpawnAttackerFailSafe) + return SpawnAttackerFailSafe + + EndIf + +EndFunction + +ObjectReference Function GetDefenderSpawnRef(ReferenceAlias AliasToCheckFor) + ;VERY SIMILAR TO GetAttackerSpawnRef... these are different functions because I need to return attacker or defender spawn refs + + actor playerActor = Game.GetPlayer() as Actor + +; CWScript.Log("CWReinforcementControllerScript", self + "GetDefenderSpawnRef() " ) + + ObjectReference PrioritySpawn = TryToGetPrioritySpawnLinkedRef(AliasToCheckFor) + ObjectReference ForcedSpawn = TryToGetForcedSpawnLinkedRef(AliasToCheckFor) + + if ForcedSpawn +; CWScript.Log("CWReinforcementControllerScript", self + "GetDefenderSpawnRef() playerActor.HasLOS(ForcedSpawn) == False, returning " + ForcedSpawn) + return ForcedSpawn + + elseif PrioritySpawn && playerActor.HasLOS(PrioritySpawn) == False +; CWScript.Log("CWReinforcementControllerScript", self + "GetDefenderSpawnRef() playerActor.HasLOS(PrioritySpawn) == False, returning " + PrioritySpawn) + return PrioritySpawn + + elseif playerActor.HasLOS(SpawnDefender1) == False +; CWScript.Log("CWReinforcementControllerScript", self + "GetDefenderSpawnRef() playerActor.HasLOS(SpawnDefender1) == False, returning " + SpawnDefender1) + return SpawnDefender1 + + elseif playerActor.HasLOS(SpawnDefender2) == False +; CWScript.Log("CWReinforcementControllerScript", self + "GetDefenderSpawnRef() playerActor.HasLOS(SpawnDefender2) == False, returning " + SpawnDefender2) + return SpawnDefender2 + + elseif playerActor.HasLOS(SpawnDefender3) == False +; CWScript.Log("CWReinforcementControllerScript", self + "GetDefenderSpawnRef() playerActor.HasLOS(SpawnDefender3) == False, returning " + SpawnDefender3) + return SpawnDefender3 + + elseif playerActor.HasLOS(SpawnDefender4) == False +; CWScript.Log("CWReinforcementControllerScript", self + "GetDefenderSpawnRef() playerActor.HasLOS(SpawnDefender4) == False, returning " + SpawnDefender4) + return SpawnDefender4 + + else +; CWScript.Log("CWReinforcementControllerScript", self + "GetDefenderSpawnRef() playerActor.HasLOS to all the Spawn markers, returning the SpawnDefenderFailsafe:" + SpawnDefenderFailSafe) + return SpawnDefenderFailSafe + + EndIf + +EndFunction + + +Function RegisterSpawnAttackerAliases(ReferenceAlias Marker1Alias, ReferenceAlias Marker2Alias, ReferenceAlias Marker3Alias, ReferenceAlias Marker4Alias, ReferenceAlias FailSafeMarkerAlias) + +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterSpawnAttackerMarkersAsAliases() adding ReferenceAlias references.") + + SpawnAttacker1 = Marker1Alias.GetReference() + SpawnAttacker2 = Marker2Alias.GetReference() + SpawnAttacker3 = Marker3Alias.GetReference() + SpawnAttacker4 = Marker4Alias.GetReference() + SpawnAttackerFailSafe = FailSafeMarkerAlias.GetReference() + + +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterSpawnAttackerMarkersAsAliases() SpawnAttacker1 = " + SpawnAttacker1 ) +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterSpawnAttackerMarkersAsAliases() SpawnAttacker2 = " + SpawnAttacker2 ) +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterSpawnAttackerMarkersAsAliases() SpawnAttacker3 = " + SpawnAttacker3 ) +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterSpawnAttackerMarkersAsAliases() SpawnAttacker4 = " + SpawnAttacker4 ) +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterSpawnAttackerMarkersAsAliases() SpawnAttackerFailSafe = " + SpawnAttackerFailSafe ) + +EndFunction + +Function RegisterSpawnDefenderAliases(ReferenceAlias Marker1Alias, ReferenceAlias Marker2Alias, ReferenceAlias Marker3Alias, ReferenceAlias Marker4Alias, ReferenceAlias FailSafeMarkerAlias) + +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterSpawnDefenderMarkersAsAliases() adding ReferenceAlias references.") + + SpawnDefender1 = Marker1Alias.GetReference() + SpawnDefender2 = Marker2Alias.GetReference() + SpawnDefender3 = Marker3Alias.GetReference() + SpawnDefender4 = Marker4Alias.GetReference() + SpawnDefenderFailSafe = FailSafeMarkerAlias.GetReference() + +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterSpawnDefenderMarkersAsAliases() SpawnDefender1 = " + SpawnDefender1 ) +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterSpawnDefenderMarkersAsAliases() SpawnDefender2 = " + SpawnDefender2 ) +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterSpawnDefenderMarkersAsAliases() SpawnDefender3 = " + SpawnDefender3 ) +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterSpawnDefenderMarkersAsAliases() SpawnDefender4 = " + SpawnDefender4 ) +; CWScript.Log("CWReinforcementControllerScript", self + "RegisterSpawnDefenderMarkersAsAliases() SpawnDefenderFailSafe = " + SpawnDefenderFailSafe ) +EndFunction + + + +Function setInfinitePools(bool AttackerHasInfinite = true, bool DefenderHasInfinite = true) +{THIS MUST BE CALLED AFTER CALLING SetPoolAttacker/Defender, or in place of calling those} +;both params are true for backwards compatability when this function set a single variable meaning ALL respawns were infinite + +; CWScript.Log("CWReinforcementControllerScript", self + "setInfinitePools( AttackerHasInfinite==" + AttackerHasInfinite + ", DefenderHasInfinite==" + DefenderHasInfinite + ")") + + if AttackerHasInfinite + PoolAttacker = 9999 + StartingPoolAttacker = 9999 + InfiniteRespawnAttacker = AttackerHasInfinite + + EndIf + + + if DefenderHasInfinite + PoolDefender = 9999 + StartingPoolDefender = 9999 + InfiniteRespawnDefender = DefenderHasInfinite + endif + +EndFunction + +Function SetPoolAttacker(int BasePool = 10, float AttackDeltaMult = 1.0, float scaleMult = 1.0, bool InfinitePool = False) +{PoolAttacker = (BasePool + (AttackDelta * AttackDeltaMult) | 0)) * scaleMult } + + float pool + + + if infinitePool == False + + ;int AttackDelta = CWCampaignS.GetCurrentAttackDelta() + ;ATTACK DELTA IS NO LONGER BEING USED - IT WAS THE RELATIVE STRENGTH OF THE ATTACKER BASED ON THE SURROUNDING HOLDS HE OWNS ADJACENT TO THE CONTESTED HOLD. THERE IS NO CURRENT CAMPAIGN WITH CONTESTED HOLD ANYMORE + ;To make life easier for me, I'm just setting attack delta to 0 rather than restructuring all the logic + + int AttackDelta = 0 + + if AttackDelta > 0 + + pool = (BasePool + (AttackDelta * AttackDeltaMult)) * scaleMult +; CWScript.Log("CWReinforcementControllerScript", self + "SetPoolAttacker() Pool[" + Pool + "] = (BasePool[" + BasePool + "] + (AttackDelta[" + AttackDelta + "] * AttackDeltaMult[" + AttackDeltaMult + "])) * scaleMult[" + scaleMult + "]" ) + + Else + + pool = BasePool * scaleMult +; CWScript.Log("CWReinforcementControllerScript", self + "SetPoolAttacker() Pool[" + Pool + "] = BasePool[" + BasePool + "] * scaleMult[" + scaleMult + "]" ) + + EndIf + + PoolAttacker = pool as int + StartingPoolAttacker = pool as int + + Else +; CWScript.Log("CWReinforcementControllerScript", self + "SetPoolAttacker() is making Attackers have an Infinite Pool.") + setInfinitePools(AttackerHasInfinite = true, DefenderHasInfinite = False) ;doesn't set it to false, just doesn't set it to true + + EndIf + + CWs.CWPercentPoolRemainingAttacker.setValue(100) + PoolRemainingObjectiveQuest.UpdateCurrentInstanceGlobal(CWs.CWPercentPoolRemainingAttacker) + +; CWScript.Log("CWReinforcementControllerScript", self + "SetPoolAttacker() PoolAttacker = " + PoolAttacker ) + +EndFunction + + +Function SetPoolDefender(int BasePool = 10, float AttackDeltaMult = 1.0, float scaleMult = 1.0, bool InfinitePool = False) +{PoolDefender = (BasePool + (|-AttackDelta| * AttackDeltaMult) | 0)) * scaleMult } + + float pool + + + if infinitePool == False + + ;int AttackDelta = CWCampaignS.GetCurrentAttackDelta() + ;ATTACK DELTA IS NO LONGER BEING USED - IT WAS THE RELATIVE STRENGTH OF THE ATTACKER BASE ON THE SURROUNDING HOLDS HE OWNS ADJACENT TO THE CONTESTED HOLD. THERE IS NO CURRENT CAMPAIGN WITH CONTESTED HOLD ANYMORE + ;To make life easier for me, I'm just setting attack delta to 0 rather than restructuring all the logic + + int AttackDelta = 0 + + if AttackDelta < 0 + + pool = (BasePool + (Math.ABS(AttackDelta) * AttackDeltaMult)) * scaleMult +; CWScript.Log("CWReinforcementControllerScript", self + "SetPoolDefender() Pool[" + Pool + "] = (BasePool[" + BasePool + "] + (Math.ABS(AttackDelta[" + AttackDelta + "]) * AttackDeltaMult[" + AttackDeltaMult + "])) * scaleMult[" + scaleMult + "]" ) + + + Else + + pool = BasePool * scaleMult +; CWScript.Log("CWReinforcementControllerScript", self + "SetPoolDefender() Pool[" + Pool + "] = BasePool[" + BasePool + "] * scaleMult[" + scaleMult + "]" ) + + EndIf + + PoolDefender = pool as int + StartingPoolDefender = pool as int + + Else +; CWScript.Log("CWReinforcementControllerScript", self + "SetPoolDefender() is making Defenders have an Infinite Pool.") + setInfinitePools(AttackerHasInfinite = False, DefenderHasInfinite = True) ;doesn't set it to false, just doesn't set it to true + + EndIf + + CWs.CWPercentPoolRemainingDefender.setValue(100) + PoolRemainingObjectiveQuest.UpdateCurrentInstanceGlobal(CWs.CWPercentPoolRemainingDefender) + + +; CWScript.Log("CWReinforcementControllerScript", self + "SetPoolDefender() PoolDefender = " + PoolDefender ) + +EndFunction + +function shuffleSpawnMarkers() +{Promotes each spawn alias into the next position so that the first choice of respawn point is "randomized"} + + +; CWScript.Log("CWReinforcementControllerScript", self + "shuffleSpawnAliases() shuffling Spawn Marker Aliases.") + + ObjectReference tempSpawn4 + tempSpawn4 = SpawnAttacker4 + SpawnAttacker4 = SpawnAttacker3 + SpawnAttacker3 = SpawnAttacker2 + SpawnAttacker2 = SpawnAttacker1 + SpawnAttacker1 = TempSpawn4 + + tempSpawn4 = SpawnDefender4 + SpawnDefender4 = SpawnDefender3 + SpawnDefender3 = SpawnDefender2 + SpawnDefender2 = SpawnDefender1 + SpawnDefender1 = TempSpawn4 + +EndFunction + + +function SubtractFromAttackerPool(int NumSoldiersToSubtractBy = 1) +{This function subtracts the value of a soldier from the bool} ;Note: this is occasionally called externally when we need to modify the pool for some other reason than respawning a soldier + + if InfiniteRespawnAttacker == False +; CWScript.Log("CWReinforcementControllerScript", self + "SubtractFromAttackerPool() calling ModifyPool().") + ModifyPool(true, -(NumSoldiersToSubtractBy)) + + Else +; CWScript.Log("CWReinforcementControllerScript", self + "SubtractFromAttackerPool() InfiniteRespawnAttacker == true, so NOT modifying the pool") + + EndIf + + +EndFunction + +function SubtractFromDefenderPool(int NumSoldiersToSubtractBy = 1) +{This function subtracts the value of a soldier from the bool} ;Note: this is occasionally called externally when we need to modify the pool for some other reason than respawning a soldier + + if InfiniteRespawnDefender == False +; CWScript.Log("CWReinforcementControllerScript", self + "SubtractFromDefenderPool() calling ModifyPool().") + ModifyPool(false, -(NumSoldiersToSubtractBy)) + + Else +; CWScript.Log("CWReinforcementControllerScript", self + "SubtractFromDefenderPool() InfiniteRespawnDefender == true, so NOT modifying the pool") + + EndIf + +EndFunction + +function AddBackToAttackerPool(int NumSoldiersToAddBackBy = 1) +{This function subtracts the value of a soldier from the bool} ;Note: this is occasionally called externally to add back to the pool + +; CWScript.Log("CWReinforcementControllerScript", self + "AddBackToAttackerPool() calling ModifyPool().") + ModifyPool(true, NumSoldiersToAddBackBy) + +EndFunction + +function AddBackToDefenderPool(int NumSoldiersToAddBackBy = 1) +{This function subtracts the value of a soldier from the bool} ;Note: this is occasionally called externally to add back to the pool + +; CWScript.Log("CWReinforcementControllerScript", self + "AddBackToDefenderPool() calling ModifyPool().") + ModifyPool(False, NumSoldiersToAddBackBy) + +EndFunction + +function ModifyPool(bool ModAttackerPool, int NumSoldiersToModifyBy) +{ModAttacker should be true if we are modifying attacker pool, false if modifying defender pool. NumSoldiersToModifyBy should be positve if adding to pool, or negative if subtracting from pool} + int valueToModifyBy = CostForReinforcement * NumSoldiersToModifyBy + + float percentRemaningAttacker = PoolAttacker / StartingPoolAttacker + float percentRemaningDefender = PoolDefender / StartingPoolDefender + + + if ModAttackerPool +; CWScript.Log("CWReinforcementControllerScript", self + "ModifyPool() modifying attacker pool by: " + valueToModifyBy) + PoolAttacker += valueToModifyBy + CWs.CWReinforcementPoolAttacker.SetValue(PoolAttacker) + if getStageDone(StageToSetIfAttacker25PercentRemainging) == false && percentRemaningAttacker <= 0.25 + setStage(StageToSetIfAttacker25PercentRemainging) + EndIf + + Else ;we are modifying defender pool +; CWScript.Log("CWReinforcementControllerScript", self + "ModifyPool() modifying defender pool by: " + valueToModifyBy) + PoolDefender += valueToModifyBy + CWs.CWReinforcementPoolDefender.SetValue(PoolDefender) + if getStageDone(StageToSetIfDefender25PercentRemainging) == false && percentRemaningDefender <= 0.25 + setStage(StageToSetIfDefender25PercentRemainging) + EndIf + EndIf + + ShowPoolsToPlayer() + +EndFunction + + + + +function killOffscreenDefender() +;This function kills an offscreen soldier in the defender alias "array". +;This is called by CWFortSiege Interior Defender Aliases on Death to give a reward to attacker for killing an interior defender, because interior defenders don't respawn normally +;See CWFortSiegeInteriorDefenderScript +; CWScript.Log("CWReinforcementControllerScript", self + "killOffscreenDefender()") + + bool success + + if tryToKillOffscreenDefender(D1) + success = true + elseif tryToKillOffscreenDefender(D2) + success = true + elseif tryToKillOffscreenDefender(D3) + success = true + elseif tryToKillOffscreenDefender(D4) + success = true + elseif tryToKillOffscreenDefender(D5) + success = true + elseif tryToKillOffscreenDefender(D6) + success = true + elseif tryToKillOffscreenDefender(D7) + success = true + elseif tryToKillOffscreenDefender(D8) + success = true + elseif tryToKillOffscreenDefender(D9) + success = true + elseif tryToKillOffscreenDefender(D10) + success = true + elseif tryToKillOffscreenDefender(D11) + success = true + elseif tryToKillOffscreenDefender(D12) + success = true + elseif tryToKillOffscreenDefender(D13) + success = true + elseif tryToKillOffscreenDefender(D14) + success = true + elseif tryToKillOffscreenDefender(D15) + success = true + elseif tryToKillOffscreenDefender(D16) + success = true + elseif tryToKillOffscreenDefender(D17) + success = true + elseif tryToKillOffscreenDefender(D18) + success = true + elseif tryToKillOffscreenDefender(D19) + success = true + elseif tryToKillOffscreenDefender(D20) + success = true + EndIf + + if success +; CWScript.Log("CWReinforcementControllerScript", self + "killOffscreenDefender() found an offscreen defender and killed him.") + Else +; CWScript.Log("CWReinforcementControllerScript", self + "killOffscreenDefender() could not find an offscreen defender so didn't kill anyone.", 1) + EndIf + +EndFunction + +bool function tryToKillOffscreenDefender(ReferenceAlias AliasToTryToKill) + Actor AliasActor = AliasToTryToKill.GetActorReference() + + if AliasActor + if AliasActor.IsDead() == false && AliasActor.IsInInterior() == False + if Game.GetPlayer().IsInInterior() == True + if AliasActor.GetParentCell() != Game.GetPlayer().GetParentCell() +; CWScript.Log("CWReinforcementControllerScript", self + "tryToKillOffscreenDefender() killing " + AliasActor + " in alias " + AliasToTryToKill) + AliasActor.kill() + Return True + EndIf + EndIf + EndIf + EndIf + +; CWScript.Log("CWReinforcementControllerScript", self + "tryToKillOffscreenDefender() NOT killing " + AliasActor + " in alias " + AliasToTryToKill + "because he's not not dead, not in an exterior, the player isn't in an interior, or they are in the same interior.") + return False + +EndFunction + + +int function getPoolExpressedAsSoldierCount(float Pool) +{returns Pool/Cost per soldier} + + int soldiers = math.floor(Pool / CostForReinforcement) as Int + + if soldiers < 0 + soldiers = 0 + EndIf + +; CWScript.Log("CWReinforcementControllerScript", self + "getPoolExpressedAsSoldierCount() returning: " + soldiers) + + return soldiers + +EndFunction + +function ShowPoolsToPlayer() +; CWScript.Log("CWReinforcementControllerScript", self + "ShowPoolsToPlayer() PoolAttacker=" + PoolAttacker +", PoolDefender=" + PoolDefender) + TryToShowAttackerPools() + TryToShowDefenderPools() + +EndFunction + +int function GetThresholdCounter(float startingPool, float CurrentPool, float PercentThreshold = 5.0) +{Returns an int that when it "ticks" means it's time to show the pool to the player (for example every 5% of reinforcements)} + +; CWScript.Log("CWReinforcementControllerScript", self + "GetThresholdCounter() startingPool: " + startingPool + ", CurrentPool: " + CurrentPool + ", PercentThreshold:" + PercentThreshold) + + ;convert pools to soldier counts incase we later change the cost per soldier + startingPool = getPoolExpressedAsSoldierCount(startingPool) + CurrentPool = getPoolExpressedAsSoldierCount(currentPool) + + ;chunk the percentage into an integer we can compare to the last time + float thresholdCounter = currentPool / startingPool * 100 / PercentThreshold + +; CWScript.Log("CWReinforcementControllerScript", self + "GetThresholdCounter() returning: " + thresholdCounter as int) + + return thresholdCounter as int + +EndFunction + +function TryToShowAttackerPools() + + int currentThresholdCounter + + if ShowAttackerPoolObjective +; CWScript.Log("CWReinforcementControllerScript", self + "TryToShowAttackerPools() will check to see if enough tickets were lost to display the number again.") + + currentThresholdCounter = GetThresholdCounter(StartingPoolAttacker, PoolAttacker, 5) + + if ThresholdCounterPoolAttacker == -999 ;initialized value + ThresholdCounterPoolAttacker = currentThresholdCounter + ShowAttackerPool() + EndIf + + if currentThresholdCounter < ThresholdCounterPoolAttacker + ;then we've reached the next 5% threshold + ThresholdCounterPoolAttacker -= 1 + ShowAttackerPool() + Else + ;then we didn't reach the next 5% threshold so don't show the pool to the player +; CWScript.Log("CWReinforcementControllerScript", self + "TryToShowAttackerPools() found it's not yet time to display the number again. CurrentThresholdCounter: " + currentThresholdCounter + " is not > than ThresholdCounterPoolAttacker:" + ThresholdCounterPoolAttacker) + + EndIf + + Else + ;we aren't supposed to show +; CWScript.Log("CWReinforcementControllerScript", self + "TryToShowAttackerPools() isn't supposed to show Attacker Pool.") + EndIf + +EndFunction + +function TryToShowDefenderPools() + + int currentThresholdCounter + + if ShowDefenderPoolObjective +; CWScript.Log("CWReinforcementControllerScript", self + "TryToShowDefenderPools() will check to see if enough tickets were lost to display the number again.") + + currentThresholdCounter = GetThresholdCounter(StartingPoolDefender, PoolDefender, 7) + + if ThresholdCounterPoolDefender == -999 ;initialized value + ThresholdCounterPoolDefender = currentThresholdCounter + ShowDefenderPool() + EndIf + + if currentThresholdCounter < ThresholdCounterPoolDefender + ;then we've reached the next 5% threshold + ThresholdCounterPoolDefender -= 1 + ShowDefenderPool() + Else + ;then we didn't reach the next 5% threshold so don't show the pool to the player +; CWScript.Log("CWReinforcementControllerScript", self + "TryToShowDefenderPools() found it's not yet time to display the number again. CurrentThresholdCounter: " + currentThresholdCounter + " is not > than ThresholdCounterPoolDefender:" + ThresholdCounterPoolDefender) + + EndIf + + Else + ;we aren't supposed to show +; CWScript.Log("CWReinforcementControllerScript", self + "TryToShowDefenderPools() isn't supposed to show Defender Pool.") + EndIf + +EndFunction + +function showAttackerPool() + + float percentRemaning = PoolAttacker / StartingPoolAttacker + +; CWScript.Log("CWReinforcementControllerScript", self + "showAttackerPool() Attackers % Remaining =" + percentRemaning) + + CWs.CWPercentPoolRemainingAttacker.setValue((percentRemaning * 100) as Int) + PoolRemainingObjectiveQuest.UpdateCurrentInstanceGlobal(CWs.CWPercentPoolRemainingAttacker) + + + if CWs.CWPercentPoolRemainingAttacker.GetValue() > 0 + PoolRemainingObjectiveQuest.SetObjectiveDisplayed(PoolRemainingAttackerObjective, true, true) + Else + PoolRemainingObjectiveQuest.SetObjectiveDisplayed(PoolRemainingAttackerObjective) + PoolRemainingObjectiveQuest.SetObjectiveCompleted(PoolRemainingAttackerObjective) + endif + + +EndFunction + +function showDefenderPool() + + float percentRemaning = PoolDefender / StartingPoolDefender + +; CWScript.Log("CWReinforcementControllerScript", self + "showDefenderPool() Defenders % Remaining =" + percentRemaning) + + CWs.CWPercentPoolRemainingDefender.setValue((percentRemaning * 100) as Int) + PoolRemainingObjectiveQuest.UpdateCurrentInstanceGlobal(CWs.CWPercentPoolRemainingDefender) + + + if CWs.CWPercentPoolRemainingDefender.GetValue() > 0 + PoolRemainingObjectiveQuest.SetObjectiveDisplayed(PoolRemainingDefenderObjective, true, true) + Else + PoolRemainingObjectiveQuest.SetObjectiveDisplayed(PoolRemainingDefenderObjective) + PoolRemainingObjectiveQuest.SetObjectiveCompleted(PoolRemainingDefenderObjective) + endif + +EndFunction diff --git a/source/scripts/cwscript.psc b/source/scripts/cwscript.psc new file mode 100644 index 00000000..9dc32c7a --- /dev/null +++ b/source/scripts/cwscript.psc @@ -0,0 +1,5288 @@ +Scriptname CWScript extends Quest Conditional +{Main script for the Civil War, holds many "global" properties for the system.} + +;NOTE: +;The Civil War has gone through many iterations. There's a lot of obsolete stuff in here from previous iterations where it was more dynamic and free form. +;So if you're a modder looking for scripting examples, while there's some interesting things going on in here, the CW scripts are probably not the best place to start. There's a lot of obsolete and deprecated complexity in these systems + +;#POINTER TO GLOBAL SHOW DEBUG TRACES +GlobalVariable property debugOn auto conditional ;###This is largely obsolete property, but there are a few things that still refer to it. See the Log() function below for the new way to do this ;0 = unset, 1 = set - show warnings +{Pointer to Global CWDebugOn, used to toggle on trace spam} + +;Variables +;int property debugForceAttacker auto conditional hidden ;0 = unset, 1 = force the attacker to always be Imperials, 2 = Sons of Skyrim; see stage 10 +;int property debugForceHold auto conditional hidden ;0 = unset, 1 = force the Contested Hold to be this enum value (see contestedHold variable below for enums) + +GlobalVariable Property CWDebugForceAttacker Auto +GlobalVariable Property CWDebugForceHold Auto +GlobalVariable Property CWDebugAllowCampaignsInFinalHolds Auto + +int property debugForceOffscreenResult auto conditional hidden ;The next time the campaign updates it's script, it will force an Offscreen resolution, Note: this also forces the Quest Delay time to be a frame long to speed everything up +int property debugDBTraces auto conditional hidden ;0 = unset, 1 = export warnings that are database friendly + +int Property debugTreatCityCapitalsAsTowns auto Conditional Hidden ;0 = unset, 1 = causes Cities such as Whiterun, to be considered towns and start minor hold resolution quests +int Property debugStartingCampaignPhase auto Conditional Hidden ;0 = unset, N = the phase that the campaign starts in, for example, you could force the campaign to always start in the resolution phase if you need to test a resolution quest + +int Property debugAllowNonAdjacentHolds Auto Conditional Hidden ;0 = unset, 1 = allow attacks against holds where attacker has no adjacent holds + +int property debugSkipSetOwnerCalls auto Hidden ;0 unset, 1 = ignore calls to setOwner... breaks things but causes Civil War campaign to start much faster for certain types of play testing + +;tracking variables +int property countCampaigns auto conditional Hidden ;how many campaigns have run +int property countWinImperials auto conditional Hidden ;how many times have the Imperials won a campaign +int property countWinSons auto conditional Hidden ;how many times have the Sons won a campaign + +;how many times has the faction won this hold +int property countWinReachImperials auto conditional Hidden +int property countWinReachSons auto conditional Hidden +int property countWinHjaalmarchImperials auto conditional Hidden +int property countWinHjaalmarchSons auto conditional Hidden +int property countWinWhiterunImperials auto conditional Hidden +int property countWinWhiterunSons auto conditional Hidden +int property countWinFalkreathImperials auto conditional Hidden +int property countWinFalkreathSons auto conditional Hidden +int property countWinPaleImperials auto conditional Hidden +int property countWinPaleSons auto conditional Hidden +int property countWinWinterholdImperials auto conditional Hidden +int property countWinWinterholdSons auto conditional Hidden +int property countWinRiftImperials auto conditional Hidden +int property countWinRiftSons auto conditional Hidden + +int Property campaignRunning auto Conditional Hidden ;(set in CWCampaign stage 0) 0 = not running, 1 = busy setting up campaign, 2 = done setting up and other quests and scripts can assume its safe to poke the campaign + + +;Offscreen resolution stuff +float property resolutionAttackDeltaMultiplier auto conditional Hidden ;(set in the "init" block below) the value that gets multipled to the attack Delta in the offscreen resolution formula before being added to the die roll +float property resolutionDieRoll auto conditional Hidden ;1-100, gets adding to the AttackDelta*Multiplier in the offscreen resolution formula +Bool Property resolutionForced auto conditional Hidden ;True = Defender is forced to be the winner because the player wasn't yet involved in the campaign for the hold which was a major hold with a city (we don't want cities changing hands if the player never got involved) +float property resolutionResult auto conditional Hidden ;> 50 = Attacker wins, <= 50 means Defender wins + +int property playerAllegiance auto conditional Hidden ;0 = unset, 1 = player joined Imperials, 2 = Sons of Skyrim -- note before the player commits in the main quest, the system still needs him to be on a "side" because it assumes he always is on a side, in CW Stage 0 it puts him in Imperials if he isn't already commited +;REM'd out bit below is used to debug if a script is setting this incorrectly somwhere +;int playerAllegianceVar +;int Property playerAllegiance Hidden +; function set(int value) +; ; debug.tracestack("*playerAllegiance = "+value) +; playerAllegianceVar = value +; EndFunction +; int function get() +; return playerAllegianceVar +; EndFunction +;EndProperty + + +int property playerJoinedCampaginReach auto conditional Hidden ;0 = unset, 1 = player took a mission in that hold. Until this = 1 any offscreen resolution will always fail for the attacker. This ensures that the player has a chance to see "pre-switched" state and see the new Jarl's plot arc. +int property playerJoinedCampaginWhiterun auto conditional Hidden +int property playerJoinedCampaginRift auto conditional Hidden +int Property PlayerJoinedCurrentCampaign auto Hidden ;used for determining salary, set in CWMissionScript PlayerAcceptsMission() + +int Property TutorialMissionComplete Auto Conditional Hidden ;0 = unset, 1 = player completed the tutorial mission -- this changes the behavior of the resolution phase. (See CWCampaignScript StartMissions()) Until the player completes the tutorial, resolution phase will finish offscreen immediately. + +int Property PlayerGotIntro Auto Conditional hidden ;player got the "do i know you? I was at helgen? Oh, you were at helgen" stuff from one of the factions, used to make the other faction recognize you right away so you don't have go through all that again + +int property playerInvolved auto conditional Hidden ;0 = unset, 1 = the player is now involved in the Civil War +int Property WarIsActive Auto Conditional Hidden ;0 = not set, 1 = active and player can get missions from field cos, -1 = paused and should not start new missions + +bool Property EnemyFortsAddedBackToWar auto conditional Hidden ;see AddEnemyFortsBackToWar() + +int property playerReport auto conditional Hidden ;See FinishCampaign() - 0 = un/reset, 1 = player should report, 2 = player reported to faction head after campaign + +bool Property WhiterunSiegeStarted Auto Hidden ;used by CWFieldCOScript if the whiterun siege has started, don't try starting it again +bool Property WhiterunSiegeFinished Auto conditional Hidden ;means the initial siege of whiterun has either been won, or lost + +int property contestedHoldWinner auto conditional Hidden ;1 = Imperials, 2 = Sons +int Property contestedHoldWinType auto Conditional Hidden ;0 = unset, 1 = Attacker won, 2 Defender won + +float property attackerCoinToss auto conditional Hidden ;0 = unset, 1 = imperials, 2=Sons of Skyrim (see CW Stage 10) +int property previousAttacker auto conditional Hidden ;0 = unset, 1 = Imperials, 2=Sons of Skyrim +int property consecutiveAttacks auto conditional Hidden ;0 = unset/reset, # = number of times the same side attacked (used to force change if randomly picks the same one too many times in arow) + +;ints representing each side, corresponds to other variables that store 1 or 2 to mean Imperials or Sons... for testing things like: "if attacker == iImperials" +int Property iImperials = 1 Auto Hidden +int Property iSons = 2 Auto Hidden +int Property iBothFactions = 3 Auto Hidden + +int Property iCurrentOwner = -999 Auto Hidden ;used by SetOwner and it's related functions (means just reset the garrison, don't change the owner) + +int property attacker auto conditional Hidden ;0 = unset, 1 = Imperials, 2=Sons of Skyrim +int property defender auto conditional Hidden ;0 = unset, 1 = Imperials, 2=Sons of Skyrim +int property choosingHold auto conditional Hidden ;0 = unset, ;N = iteration of trying to chose a hold to attack, -N means successful after N tries (see game mode block) + +;properties representing holds as ints +int Property iHaafingar = 1 auto Hidden ;* can't be contested +int Property iReach = 2 auto Hidden +int Property iHjaalmarch = 3 auto Hidden +int Property iWhiterun = 4 auto Hidden +int Property iFalkreath = 5 auto Hidden +int Property iPale = 6 auto Hidden +int Property iWinterhold = 7 auto Hidden +int Property iEastmarch = 8 auto Hidden ;* can't ne contested +int Property iRift = 9 auto Hidden +;list for ease of copying and pasting: +;iHaafingar iReach iHjaalmarch iWhiterun iFalkreath iPale iWinterhold iEastmarch iRift + +;list of hold names +;Haafingar Reach Hjaalmarch Whiterun Falkreath Pale Winterhold Eastmarch Rift + +int property contestedHold auto conditional Hidden +int property previousContestedHold auto conditional Hidden +;enums meaning which hold is contested - these are same values as assigned to iHaafinager, iReach, etc. so you can test 'contestedHold == iReach', etc. +;0 = unset +;1 = Haafingar* +;2 = Reach +;3 = Hjaalmarch +;4 = Whiterun +;5 = Falkreath +;6 = Pale +;7 = Winterhold +;8 = Eastmarch* +;9 = Rift +;* can't be contested + +;Current Owner of Holds ;0 = unset, 1 = Imperial controlled, 2 = Sons of Skyrim controlled +int property OwnerHaafingar auto conditional Hidden +int property OwnerReach auto conditional Hidden +int property OwnerHjaalmarch auto conditional Hidden +int property OwnerWhiterun auto conditional Hidden +int property OwnerFalkreath auto conditional Hidden +int property OwnerPale auto conditional Hidden +int property OwnerWinterhold auto conditional Hidden +int property OwnerEastmarch auto conditional Hidden +int property OwnerRift auto conditional Hidden + +int property ownerContestedHold auto conditional Hidden ;0 = unset, 1 = Imperial controlled, 2 = Sons of Skyrim controlled + +int property countHoldsImperial auto Conditional Hidden ;how many holds do the Imperials currently control +int property countHoldsSons auto Conditional Hidden ;how many holds to the Sons currently control + + +;Adjacency info (if any of this changes, make sure the function that compute Strength Values is changed accordingly) +;Haafingar Reach, Hjaalmarch +;Reach Haafingar, Hjaalmarch, Whiterun, Falkreath +;Hjaalmarch Haafingar, Reach, Whiterun, Pale +;Whiterun Reach, Hjaalmarch, Falkreath, Pale, Eastmarch, Rift +;Falkreath Reach, Whiterun, Rift +;Pale Hjaalmarch, Whiterun, Winterhold, Eastmarch +;Winterhold Pale, Eastmarch +;Eastmarch Winterhold, Pale, Whiterun, Rift +;Rift Whiterun, Falkreath, Eastmarch + + + +;Strength Value of Holds ;0 = unset, N = number of Strength Value points this hold is worth when adjacent to contested hold +int property StrValueHaafingar auto Hidden +int property StrValueReach auto Hidden +int property StrValueHjaalmarch auto Hidden +int property StrValueWhiterun auto Hidden +int property StrValueFalkreath auto Hidden +int property StrValuePale auto Hidden +int property StrValueWinterhold auto Hidden +int property StrValueEastmarch auto Hidden +int property StrValueRift auto Hidden + + +;Strength Points per hold for each faction (used by setStrengthPoints()) 0 = doesn't own adjacent holds, N= total of Strength Value points contributed by adjacent holds controlled by faction +int property strHaafingarImperial auto conditional Hidden +int property strHaafingarSons auto conditional Hidden +int property strReachImperial auto conditional Hidden +int property strReachSons auto conditional Hidden +int property strHjaalmarchImperial auto conditional Hidden +int property strHjaalmarchSons auto conditional Hidden +int property strWhiterunImperial auto conditional Hidden +int property strWhiterunSons auto conditional Hidden +int property strFalkreathImperial auto conditional Hidden +int property strFalkreathSons auto conditional Hidden +int property strPaleImperial auto conditional Hidden +int property strPaleSons auto conditional Hidden +int property strWinterholdImperial auto conditional Hidden +int property strWinterholdSons auto conditional Hidden +int property strEastmarchImperial auto conditional Hidden +int property strEastmarchSons auto conditional Hidden +int property strRiftImperial auto conditional Hidden +int property strRiftSons auto conditional Hidden + +int property strContestedHoldImperial auto conditional Hidden ;same as above, but localized for currently Contested Hold +int property strContestedHoldSons auto conditional Hidden + +int property strAttacker auto conditional Hidden ;same as above, but localized for the current Attacker +int property strDefender auto conditional Hidden ;same as above, but localized for the current Defender + +int property MaxAttackDelta auto conditional Hidden ;the max attack delta can be +int property AttackDelta auto conditional Hidden ;Current Relative Attacker Strength - initally equal to (strAttacker - strDefender), it is modified by completing objectives in free form game play and missions +int property PurchaseDelta auto conditional Hidden ;The AttackDelta in a form that can be subtracted from to "pay for" locations in the contested hold (see each Campaign Quest Stage 20) + + +;Costs associated with Garrison types (see SetGarrisonCost() and SetInitialGarrisonCosts()) +int Property iCostNonContestable Auto Hidden +int Property iCostFort Auto Hidden +int Property iCostSmall Auto Hidden +int Property iCostMedium Auto Hidden +int Property iCostLarge Auto Hidden +int Property iCostPatrol Auto Hidden + +;Holds the location that was last "attacked" in the civil war... attack, sabotaged, etc. Used primarily by MQ302 scene dialogue, but could be useful elsewhere (general rumors, etc.) +;Set by CWMissionScript->RegisterLocationWasRaidedByAttacker() +Location Property LastLocAttackedByImperials Auto Hidden +Location Property LastLocAttackedBySons Auto Hidden +Location Property LastLocAttacked Auto Hidden + + +bool Property WinHoldAndSetOwnerAlreadySetKeyword Auto Hidden ;used in conjunction with WinHoldAndSetOwnerKeywordDataOnly and WinHoldAndSetOwner +bool Property WinningHoldAndSettingOwnerPleaseWait Auto Hidden ;used in conjunction with WinHoldAndSetOwnerKeywordDataOnly and WinHoldAndSetOwner + +Bool Property WaitingForCWResetGarrisonQuest1 auto Hidden ;SEE SetOwner() function below - set in SetOwner() cleared in CWResetGarrison1 shutdown stage +Bool Property WaitingForCWResetGarrisonQuest2 auto Hidden ;SEE SetOwner() function below - set in SetOwner() cleared in CWResetGarrison2 shutdown stage +Bool Property WaitingForCWResetGarrisonQuest3 auto Hidden ;SEE SetOwner() function below - set in SetOwner() cleared in CWResetGarrison3 shutdown stage +Bool Property WaitingForCWResetGarrisonQuest4 auto Hidden ;SEE SetOwner() function below - set in SetOwner() cleared in CWResetGarrison4 shutdown stage +Bool Property WaitingForCWResetGarrisonQuest5 auto Hidden ;SEE SetOwner() function below - set in SetOwner() cleared in CWResetGarrison5 shutdown stage +Bool Property WaitingForCWResetGarrisonQuest6 auto Hidden ;SEE SetOwner() function below - set in SetOwner() cleared in CWResetGarrison6 shutdown stage +Bool Property WaitingForCWResetGarrisonQuest7 auto Hidden ;SEE SetOwner() function below - set in SetOwner() cleared in CWResetGarrison7 shutdown stage +Bool Property WaitingForCWResetGarrisonQuest8 auto Hidden ;SEE SetOwner() function below - set in SetOwner() cleared in CWResetGarrison8 shutdown stage + + +int property init auto Hidden ;the 1 = OnInit() event was called +;int initvar +;int property init Hidden ;the 1 = OnInit() event was called +;function set(int value) +; ; debug.tracestack("*init = "+value) +; initvar = value +;EndFunction +;int function get() +; return initvar +;EndFunction +;endproperty + + + +;Player Rank + +int Property PlayerRank Auto Conditional Hidden ;the rank the player is in the Faction +int property CountMissionSuccess Auto Conditional Hidden ;the number of successful missions +Float Property baseSalary Auto hidden ;amount in gold the player's base campaign salary is +Float Property SalaryMultRank1 Auto hidden ;multiplier to baseSalary based on player rank +Float Property SalaryMultRank2 Auto hidden ;multiplier to baseSalary based on player rank +Float Property SalaryMultRank3 Auto hidden ;multiplier to baseSalary based on player rank +Float Property SalaryMultRank4 Auto hidden ;multiplier to baseSalary based on player rank +int Property Salary Auto conditional Hidden ;holds the total of uncollected player salary see ContributeSalaryPool() and PaySalary(), used as condition on dialogue + + +Bool Property BuddyDialogueAllowed auto conditional hidden ;set in stage 30 of CW02A/B and conditioned in buddy dialogue so you don't get the dialogue before Korvanjund + + +int Property CWMission03Done auto Conditional Hidden ;used by story manager, set in mission quest stage results +int Property CWMission04Done auto Conditional Hidden ;used by story manager, set in mission quest stage results +int Property CWMission07Done auto Conditional Hidden ;used by story manager, set in mission quest stage results + +bool Property HaafingarFortBattleComplete auto hidden ;set in CWFortSiegeFort stage 9000 +bool Property EastmarchFortBattleComplete auto hidden ;set in CWFortSiegeFort stage 9000 + +;##### Properties with pointers to things in the master file: +;### + +;## Globals ## +GlobalVariable Property CWMaxConsecutiveAttacks Auto ;this is a global variable so we can more easily tweak this setting as we play +GlobalVariable Property GameDaysPassed Auto ;Pointer to GameDaysPassed +GlobalVariable Property CWAttacker Auto ;set in StartNewCampaign() same as Attacker property +GlobalVariable Property CWDefender Auto ;set in StartNewCampaign() same as Defender property +GlobalVariable Property CWPlayerAllegiance Auto ;Global value that holds the playerAllegiance property value +GlobalVariable Property TimeScale Auto +GlobalVariable Property CWCountHoldsImperial Auto ;Holds countHoldsImperial property, set in SetHoldsImperial() function, called by SetHoldsProperty() function +GlobalVariable Property CWCountHoldsSons Auto ;Holds countHoldsImperial property, set in SetHoldsImperial() function, called by SetHoldsProperty() function +GlobalVariable Property CWContestedHold Auto ;Holds the same value as ContestedHold, used for conditions in dialogue, packages, etc. +GlobalVariable Property CWReinforcementPoolAttacker auto ;Holds the CWReinforcementControllerScript.PoolAttacker value for the current siege. +GlobalVariable Property CWReinforcementPoolDefender Auto ;Holds the CWReinforcementControllerScript.PoolAttacker value for the current siege. +GlobalVariable Property CWMissionFailDay Auto ;Holds the timestamp left before the active mission fails. Used mission journal. See CWMissionPollForFailDayScript +GlobalVariable Property CWMissionsForRank1 Auto ;Holds the number of successful missions needed for increasing the player's faction rank +GlobalVariable Property CWMissionsForRank2 Auto ;Holds the number of successful missions needed for increasing the player's faction rank +GlobalVariable Property CWMissionsForRank3 Auto ;Holds the number of successful missions needed for increasing the player's faction rank +GlobalVariable Property CWMissionsForRank4 Auto ;Holds the number of successful missions needed for increasing the player's faction rank + +GlobalVariable Property CWCountMissionsDone Auto ;DEPRECATED/OBSOLETE -- used to conditionalize story manager to allow each quest + +GlobalVariable property CWThreatBridgeImperial Auto +GlobalVariable property CWThreatBridgeSons Auto +GlobalVariable property CWThreatFenceImperial Auto +GlobalVariable property CWThreatFenceImperialArcher Auto +GlobalVariable property CWThreatFenceImperialMage Auto +GlobalVariable property CWThreatFenceSons Auto +GlobalVariable property CWThreatFenceSonsArcher Auto +GlobalVariable property CWThreatFenceSonsMage Auto +GlobalVariable property CWThreatHouseImperial Auto +GlobalVariable property CWThreatHouseSons Auto +GlobalVariable property CWThreatRockImperial Auto +GlobalVariable property CWThreatRockSons Auto +GlobalVariable property CWThreatStablesImperial Auto +GlobalVariable property CWThreatStablesSons Auto +GlobalVariable property CWThreatTowerImperial Auto +GlobalVariable property CWThreatTowerImperialArcher Auto +GlobalVariable property CWThreatTowerImperialMage Auto +GlobalVariable property CWThreatTowerSons Auto +GlobalVariable property CWThreatTowerSonsArcher Auto +GlobalVariable property CWThreatTowerSonsMage Auto +GlobalVariable property CWThreatTreeImperial Auto +GlobalVariable property CWThreatTreeSons Auto +GlobalVariable property CWThreatWallImperial Auto +GlobalVariable property CWThreatWallImperialArcher Auto +GlobalVariable property CWThreatWallImperialMage Auto +GlobalVariable property CWThreatWallSons Auto +GlobalVariable property CWThreatWallSonsArcher Auto +GlobalVariable property CWThreatWallSonsMage Auto +GlobalVariable property CWThreatWindowImperial Auto +GlobalVariable property CWThreatWindowImperialArcher Auto +GlobalVariable property CWThreatWindowImperialMage Auto +GlobalVariable property CWThreatWindowSons Auto +GlobalVariable property CWThreatWindowSonsArcher Auto +GlobalVariable property CWThreatWindowSonsMage Auto + +GlobalVariable Property CWBattlePhase Auto + +GlobalVariable Property CWPercentPoolRemainingAttacker Auto ;for use with CWReinforcementControllerScript +GlobalVariable Property CWPercentPoolRemainingDefender Auto ;for use with CWReinforcementControllerScript + +;Globals for CWObj +GlobalVariable Property CWObjEastmarch Auto +GlobalVariable Property CWObjFalkreath Auto +GlobalVariable Property CWObjHaafingar Auto +GlobalVariable Property CWObjHjaalmarch Auto +GlobalVariable Property CWObjPale Auto +GlobalVariable Property CWObjReach Auto +GlobalVariable Property CWObjRift Auto +GlobalVariable Property CWObjWhiterun Auto +GlobalVariable Property CWObjWinterhold Auto + + +;Globals for Combat Dialogue +GlobalVariable Property CWStateAttackStarted Auto +GlobalVariable Property CWStateAttackerAtGate Auto +GlobalVariable Property CWStateAttackerBrokeThrough Auto +GlobalVariable Property CWStateAttackerLowReinforcements Auto +GlobalVariable Property CWStateAttackerOutOfReinforcements Auto +GlobalVariable Property CWStateDefenderFallingBack Auto +GlobalVariable Property CWStateDefenderLastStand Auto +GlobalVariable Property CWStateDefenderLowReinforcements Auto +GlobalVariable Property CWStateDefenderOutOfReinforcements Auto + +;## Quests ## +Quest Property CWObj Auto + +Quest property CWCampaign auto +CWCampaignScript property CWCampaignS auto +Quest property CWReset auto +Quest property CWResetGarrison1 auto +Quest property CWResetGarrison2 auto +Quest property CWResetGarrison3 auto +Quest property CWResetGarrison4 auto +Quest property CWResetGarrison5 auto +Quest property CWResetGarrison6 auto +Quest property CWResetGarrison7 auto +Quest property CWResetGarrison8 auto +Quest property CWCampaignObj auto +Quest Property CWMiscObj Auto + +Quest Property CWSiegeAttackObj Auto +Quest Property CWSiegeDefendObj Auto + +CWSiegeScript Property CWSiegeS Auto +CWAlliesScript Property CWAlliesS Auto + +Quest Property CWSiegeObj Auto +Quest Property CWPrepareCity Auto + +Quest Property CWCitizensFlee Auto + +;NOTE: there used to be only one quest that was a CWFortSiege... there may be old things pointing to that specific quest, that will need to change. +;There are two because the minor capitals are using the fort siege system +Quest Property CWFortSiegeCapital Auto +Quest Property CWFortSiegeFort Auto + +Quest Property CWMission03 Auto +Quest Property CWMission04 Auto +Quest Property CWMission07 Auto + +Quest Property CWFinale Auto + +Quest Property CW00A Auto +Quest Property CW00B Auto + +Quest Property CW01A Auto +Quest Property CW01B Auto + +Quest Property CW03 Auto ;used by the CWFieldCOScript to test the quest stage to start the siege of whiterun + +Quest Property CWFin Auto + +Quest Property MQ302 Auto ;peace treaty - need to stop this if taking the second to last holds + + +WIFunctionsScript Property WIs Auto +{Pointer to WIFunctionsScript attached to WI quest} + +;## Quest Scripts ## +FavorDialogueScript Property DialogueFavorGenericS auto + +CWThreatCombatBarksScript Property CWThreatCombatBarksS Auto + + +;## Aliases ## +LocationAlias Property CWObjQuestNameLocation Auto ;see stage 1 and 2 + + +ReferenceAlias property AliasFactionLeader Auto +ReferenceAlias property AliasTullius Auto +ReferenceAlias property AliasUlfric Auto + +ReferenceAlias property ImperialFactionHQMarker Auto +ReferenceAlias property SonsFactionHQMarker Auto + +ReferenceAlias property ExiledImperialMarker Auto +ReferenceAlias property ExiledSonsMarker Auto + +ReferenceAlias Property Tullius Auto +ReferenceAlias Property Rikke Auto + +ReferenceAlias Property Ulfric Auto +ReferenceAlias Property Galmar Auto + + +ReferenceAlias Property FieldCO Auto + +ReferenceAlias Property Alias_FieldCOImperialEastmarchCamp Auto +ReferenceAlias Property Alias_FieldCOImperialEastmarchHQ Auto +ReferenceAlias Property Alias_FieldCOImperialFalkreathCamp Auto +ReferenceAlias Property Alias_FieldCOImperialFalkreathHQ Auto +ReferenceAlias Property Alias_FieldCOImperialHaafingarCamp Auto +ReferenceAlias Property Alias_FieldCOImperialHaafingarHQ Auto +ReferenceAlias Property Alias_FieldCOImperialHjaalmarchCamp Auto +ReferenceAlias Property Alias_FieldCOImperialHjaalmarchHQ Auto +ReferenceAlias Property Alias_FieldCOImperialPaleCamp Auto +ReferenceAlias Property Alias_FieldCOImperialPaleHQ Auto +ReferenceAlias Property Alias_FieldCOImperialReachCamp Auto +ReferenceAlias Property Alias_FieldCOImperialReachHQ Auto +ReferenceAlias Property Alias_FieldCOImperialRiftCamp Auto +ReferenceAlias Property Alias_FieldCOImperialRiftHQ Auto +ReferenceAlias Property Alias_FieldCOImperialWhiterunCamp Auto +ReferenceAlias Property Alias_FieldCOImperialWhiterunHQ Auto +ReferenceAlias Property Alias_FieldCOImperialWinterholdCamp Auto +ReferenceAlias Property Alias_FieldCOImperialWinterholdHQ Auto +ReferenceAlias Property Alias_FieldCOSonsEastmarchCamp Auto +ReferenceAlias Property Alias_FieldCOSonsEastmarchHQ Auto +ReferenceAlias Property Alias_FieldCOSonsFalkreathCamp Auto +ReferenceAlias Property Alias_FieldCOSonsFalkreathHQ Auto +ReferenceAlias Property Alias_FieldCOSonsHaafingarCamp Auto +ReferenceAlias Property Alias_FieldCOSonsHaafingarHQ Auto +ReferenceAlias Property Alias_FieldCOSonsHjaalmarchCamp Auto +ReferenceAlias Property Alias_FieldCOSonsHjaalmarchHQ Auto +ReferenceAlias Property Alias_FieldCOSonsPaleCamp Auto +ReferenceAlias Property Alias_FieldCOSonsPaleHQ Auto +ReferenceAlias Property Alias_FieldCOSonsReachCamp Auto +ReferenceAlias Property Alias_FieldCOSonsReachHQ Auto +ReferenceAlias Property Alias_FieldCOSonsRiftCamp Auto +ReferenceAlias Property Alias_FieldCOSonsRiftHQ Auto +ReferenceAlias Property Alias_FieldCOSonsWhiterunCamp Auto +ReferenceAlias Property Alias_FieldCOSonsWhiterunHQ Auto +ReferenceAlias Property Alias_FieldCOSonsWinterholdCamp Auto +ReferenceAlias Property Alias_FieldCOSonsWinterholdHQ Auto + +;# Aliases in OTHER quests # +LocationAlias Property CWSiegeCity Auto + +LocationAlias Property CWFortSiegeCapitalFort Auto ;fort alias in CWFortSiegeCapital + +;## Factions ## +Faction Property PlayerFaction Auto + +Faction Property CWBuddies Auto + +faction Property CWImperialFaction Auto +faction Property CWSonsFaction Auto +faction Property CWImperialFactionNPC Auto +faction Property CWSonsFactionNPC Auto + +Faction Property CWDisaffectedSoldierFaction Auto ;used for soldiers who will switch sides in CWMissions (see CWMission06 for an example) + +faction Property CrimeFactionImperial Auto ;general crime group for faction, soldiers who are attacking in a campagin should have this faction - sends criminals to faction HQ +faction Property CrimeFactionSons Auto ;general crime group for faction, soldiers who are attacking in a campagin should have this faction - sends criminals to faction HQ + +faction Property IsGuardFaction Auto + +faction Property CrimeFactionHaafingar Auto +faction Property CrimeFactionReach Auto +faction Property CrimeFactionHjaalmarch Auto +faction Property CrimeFactionWhiterun Auto +faction Property CrimeFactionFalkreath Auto +faction Property CrimeFactionPale Auto +faction Property CrimeFactionWinterhold Auto +faction Property CrimeFactionEastmarch Auto +faction Property CrimeFactionRift Auto + +faction Property CWDialogueSoldierFaction Auto +faction Property CWDialogueSoldierWaitingToAttackFaction Auto +faction Property CWDialogueSoldierWaitingToDefendFaction Auto + +faction Property CWJobFortCommanderFaction Auto +faction Property CWJobFortGatekeeperFaction Auto +faction Property CWJobFortJailorFaction Auto +faction Property CWJobFortPatrolExteriorFaction Auto + +Faction Property CWSoldierAttackerFaction Auto +Faction Property CWSoldierDefenderFaction Auto + +Faction Property CWSoldierArcherFaction Auto +Faction Property CWSoldierMageFaction Auto + +Faction Property CWSurrenderTemporaryAllies Auto + +Faction Property GovImperial Auto +Faction Property GovSons Auto + +Faction Property CWFieldCOActiveMissionFaction Auto +Faction Property CWFieldCOFailedMissionFaction Auto +Faction Property CWFieldCOHooksAcceptedFaction Auto +Faction Property CWFieldCOPotentialMission1Faction Auto +Faction Property CWFieldCOPotentialMission2Faction Auto +Faction Property CWFieldCOSuccessfulMissionFaction Auto + +Faction Property FavorAllowBribeFaction Auto + +faction Property CWRewardFactionFalkreath Auto +faction Property CWRewardFactionHjaalmarch Auto +faction Property CWRewardFactionPale Auto +faction Property CWRewardFactionReach Auto +faction Property CWRewardFactionRift Auto +faction Property CWRewardFactionWhiterun Auto +faction Property CWRewardFactionWinterhold Auto + + + +;## Locations ## + +;# Haafingar +Location property HaafingarHoldLocation auto + +Location property FortHraggstadLocation auto +Location property SolitudeLocation auto ;capital + +Location property SolitudeSawmillLocation auto +Location property KatlasFarmLocation auto +Location property DragonBridgeLocation auto + +;Location Property MilitaryCampHaafingarImperialLocation Auto +Location Property MilitaryCampHaafingarSonsLocation Auto + + +;# Reach +Location property ReachHoldLocation auto + +Location property FortSungardLocation auto +Location property MarkarthLocation auto ;capital + +Location property CidhnaMineLocation auto +Location property LeftHandMineLocation auto +Location property SalviusFarmLocation auto +Location property KarthwastenLocation auto +Location property OldHroldanLocation auto +Location property KolskeggrMineLocation auto + +Location Property MilitaryCampReachImperialLocation auto +Location Property MilitaryCampReachSonsLocation Auto + +;# Hjaalmarch +Location property HjaalmarchHoldLocation auto + +Location property FortSnowhawkLocation auto +Location property MorthalLocation auto ;capital + +Location property StonehillsLocation auto +;Location property FrostRiverFarmLocation auto ;OBSOLETE -- GONE NOT IN GAME + +Location Property MilitaryCampHjaalmarchImperialLocation auto +Location Property MilitaryCampHjaalmarchSonsLocation Auto + +;# Whiterun +Location property WhiterunHoldLocation auto + +Location property FortGreymoorLocation auto +Location property WhiterunLocation auto ;capital + +Location property BattleBornFarmLocation auto +Location property ChillfurrowFarmLocation auto +Location property PelagiaFarmLocation auto +Location property RoriksteadLocation auto +Location property RiverwoodLocation auto +;Location property BarleydarkFarmLocation auto ;OBOSETE GONE CUT FROM GAME + +Location Property MilitaryCampWhiterunImperialLocation auto +Location Property MilitaryCampWhiterunSonsLocation Auto + +;# Falkreath +Location property FalkreathHoldLocation auto + +Location property FortNeugradLocation auto +Location property FalkreathLocation auto ;capital + +;Location property GraniteHillLocation auto CUT FROM GAME +Location property HelgenLocation auto +;Location property BearsCaveMillLocation auto CUT FROM GAME +Location property HalfmoonMillLocation auto + +Location Property MilitaryCampFalkreathImperialLocation auto +Location Property MilitaryCampFalkreathSonsLocation Auto + +;# Pale +Location property PaleHoldLocation auto + +Location property FortDunstadLocation auto +Location property DawnstarLocation auto ;capital + +;Location property HeljarchenLocation auto OBSOLETE CUT FROM GAME +Location property AngasMillLocation auto +Location property LoreiusFarmLocation auto + +Location Property MilitaryCampPaleImperialLocation auto +Location Property MilitaryCampPaleSonsLocation Auto + +;# Winterhold +Location property WinterholdHoldLocation auto + +Location property FortKastavLocation auto +Location property WinterholdLocation auto ;capital + +Location property WhistlingMineLocation auto + +Location Property MilitaryCampWinterholdImperialLocation auto +Location Property MilitaryCampWinterholdSonsLocation Auto + +;# Eastmarch +Location property EastmarchHoldLocation auto + +Location property FortAmolLocation auto +Location property WindhelmLocation auto ;capital + +Location property BrandyMugFarmLocation auto +Location property HlaaluFarmLocation auto +Location property HollyfrostFarmLocation auto +Location property KynesgroveLocation auto +Location property DarkwaterCrossingLocation auto +Location property MixwaterMillLocation auto + +Location Property MilitaryCampEastmarchImperialLocation auto +;Location Property MilitaryCampEastmarchSonsLocation Auto + +;# Rift +Location property RiftHoldLocation auto + +Location property FortGreenwallLocation auto +Location property RiftenLocation auto ;capital + +Location property SnowShodFarmLocation auto +;Location property GoldenglowFarmLocation auto -- GoldenGlowFarm is NOT a normal location. It's quest specific area spawning it's own guards, and should not be part of the Civil War. +Location property MerryfairFarmLocation auto +Location property IvarsteadLocation auto +Location property ShorsStoneLocation auto +Location property HeartwoodMillLocation auto +Location property SarethiFarmLocation auto + +Location Property MilitaryCampRiftImperialLocation auto +Location Property MilitaryCampRiftSonsLocation Auto + + +;# ActorBases # + +;These are used by CWMissionScript which is used by all the CWMission quests so it's more convenient if they live here +ActorBase Property CWSoldierImperial Auto +ActorBase Property CWSoldierImperialNotGuard Auto +ActorBase Property CWSoldierSons Auto +ActorBase Property CWSoldierSonsNotGuard Auto + +ActorBase Property CWSoldierImperialNonNPCFaction Auto +ActorBase Property CWSoldierImperialNotGuardNonNPCFaction Auto +ActorBase Property CWSoldierSonsNonNPCFaction Auto +ActorBase Property CWSoldierSonsNotGuardNonNPCFaction Auto + + +ActorBase Property CWCourierImperial Auto +ActorBase Property CWCourierSons Auto +ActorBase Property CWPrisonerImperial Auto +ActorBase Property CWPrisonerSons Auto + +ActorBase Property CWPrisonerImperialA Auto +ActorBase Property CWPrisonerImperialB Auto +ActorBase Property CWPrisonerImperialC Auto +ActorBase Property CWPrisonerImperialD Auto + + +ActorBase Property CWPrisonerSonsA Auto +ActorBase Property CWPrisonerSonsB Auto +ActorBase Property CWPrisonerSonsC Auto +ActorBase Property CWPrisonerSonsD Auto + +;## Outfits ## +Outfit Property CWSoldierImperialSoldierOutfit Auto +Outfit Property CWSoldierSonsSoldierOutfit Auto + +;## MiscObjects ## +MiscObject Property Gold001 Auto ;pointer to Gold001 object + + +;## Leveled Item lists ## +LeveledItem Property CWCourierDocumentsImperial Auto ;until we have LeveledItem objects that I can point at in the editor, these are being set with GetForm() in the OnInit() block below... that needs to be removed from OnInit() block as soon as these are LeveledItem that I can set in the editor. +LeveledItem Property CWCourierDocumentsSons Auto ;until we have LeveledItem objects that I can point at in the editor, these are being set with GetForm() in the OnInit() block below... that needs to be removed from OnInit() block as soon as these are LeveledItem that I can set in the editor. + +LeveledItem Property CWRank1RewardImperial Auto ;reward player gets when gaining faction rank +LeveledItem Property CWRank2RewardImperial Auto ;reward player gets when gaining faction rank +LeveledItem Property CWRank3RewardImperial Auto ;reward player gets when gaining faction rank +LeveledItem Property CWRank4RewardImperial Auto ;reward player gets when gaining faction rank + + +LeveledItem Property CWRank1RewardSons Auto ;-intially same as imperial reward, flavored as taken from an imperial officer ;reward player gets when gaining faction rank +LeveledItem Property CWRank2RewardSons Auto ;reward player gets when gaining faction rank +LeveledItem Property CWRank3RewardSons Auto ;reward player gets when gaining faction rank +LeveledItem Property CWRank4RewardSons Auto ;reward player gets when gaining faction rank + +LeveledItem Property CWMissionReward Auto ;reward player gets after each successful mission + +LeveledItem Property CWSoldierImperialGear auto +LeveledItem Property CWSoldierSonsGear auto + +LeveledItem Property CWBearArmorPlayerReward Auto + + +;## Packages ## +Package Property CWGalmarAtCampFalkreath Auto +Package Property CWGalmarAtCampHaafingar Auto +Package Property CWGalmarAtCampHjaalmarch Auto +Package Property CWGalmarAtCampPale Auto +Package Property CWGalmarAtCampReach Auto +Package Property CWGalmarAtCampRift Auto +Package Property CWGalmarAtCampWinterhold Auto + +Package Property CWRikkeAtCampEastmarch Auto +Package Property CWRikkeAtCampFalkreath Auto +Package Property CWRikkeAtCampHjaalmarch Auto +Package Property CWRikkeAtCampPale Auto +Package Property CWRikkeAtCampReach Auto +Package Property CWRikkeAtCampRift Auto +Package Property CWRikkeAtCampWinterhold Auto + + +;## ObjectReferences ## +ObjectReference Property CWFieldCOMapTableMarkerEastmarchCampImperial Auto +ObjectReference Property CWFieldCOMapTableMarkerFalkreathCampImperial Auto +ObjectReference Property CWFieldCOMapTableMarkerHjaalmarchCampImperial Auto +ObjectReference Property CWFieldCOMapTableMarkerPaleCampImperial Auto +ObjectReference Property CWFieldCOMapTableMarkerReachCampImperial Auto +ObjectReference Property CWFieldCOMapTableMarkerRiftCampImperial Auto +ObjectReference Property CWFieldCOMapTableMarkerWhiterunCampImperial Auto +ObjectReference Property CWFieldCOMapTableMarkerWinterholdCampImperial Auto + +ObjectReference Property CWFieldCOMapTableMarkerFalkreathCampSons Auto +ObjectReference Property CWFieldCOMapTableMarkerHaafingarCampSons Auto +ObjectReference Property CWFieldCOMapTableMarkerHjaalmarchCampSons Auto +ObjectReference Property CWFieldCOMapTableMarkerPaleCampSons Auto +ObjectReference Property CWFieldCOMapTableMarkerReachCampSons Auto +ObjectReference Property CWFieldCOMapTableMarkerRiftCampSons Auto +ObjectReference Property CWFieldCOMapTableMarkerWhiterunCampSons Auto +ObjectReference Property CWFieldCOMapTableMarkerWinterholdCampSons Auto + +ObjectReference Property CWGarrisonEnableMarkerSonsCampFalkreath Auto + +;#### Actors #### +Actor Property UlfricRef Auto +Actor Property GeneralTulliusRef Auto + +Actor Property HadvarRef Auto +Actor Property RalofRef Auto + + +;# CWCampaignStart SendStoryEvent references + +;!!! *** !!! *** Don't forget to actually hook these up in the editor when they come on line !!! *** !!! *** +ObjectReference property CWCampaignStartMarkerReach auto +ObjectReference property CWCampaignStartMarkerHjaalmarch auto +ObjectReference property CWCampaignStartMarkerWhiterun auto +ObjectReference property CWCampaignStartMarkerFalkreath auto +ObjectReference property CWCampaignStartMarkerPale auto +ObjectReference property CWCampaignStartMarkerWinterhold auto +ObjectReference property CWCampaignStartMarkerRift auto + +ObjectReference property CWCampaignStartMarkerHaafingar auto +ObjectReference property CWCampaignStartMarkerEastmarch auto + + +;# Map Markers +;Military Camps +ObjectReference property MilitaryCampEastmarchImperialMapMarker auto +ObjectReference property MilitaryCampFalkreathImperialMapMarker auto +ObjectReference property MilitaryCampFalkreathSonsMapMarker auto +ObjectReference property MilitaryCampHaafingarSonsMapMarker auto +ObjectReference property MilitaryCampHjaalmarchImperialMapMarker auto +ObjectReference property MilitaryCampHjaalmarchSonsMapMarker auto +ObjectReference property MilitaryCampPaleImperialMapMarker auto +ObjectReference property MilitaryCampPaleSonsMapMarker auto +ObjectReference property MilitaryCampReachImperialMapMarker auto +ObjectReference property MilitaryCampReachSonsMapMarker auto +ObjectReference property MilitaryCampRiftImperialMapMarker auto +ObjectReference property MilitaryCampRiftSonsMapMarker auto +ObjectReference property MilitaryCampWhiterunImperialMapMarker auto +ObjectReference property MilitaryCampWhiterunSonsMapMarker auto +ObjectReference property MilitaryCampWinterholdImperialMapMarker auto +ObjectReference property MilitaryCampWinterholdSonsMapMarker auto + +ObjectReference Property CWGarrisonEnableMarkerImperialCampEastmarch Auto +ObjectReference Property CWGarrisonEnableMarkerSonsCampHaafingar Auto + + + +;## Keywords ## + +Keyword Property CWMissionStart Auto + +Keyword Property CWGarrison Auto +Keyword Property CWGarrisonDefenderOnly Auto + +Keyword Property CWFort Auto + +Keyword Property CWDiplomaticVictory Auto +Keyword Property CWOwner Auto +Keyword Property CWCampaignStart Auto +Keyword Property CWGovernmentStart Auto +Keyword Property CWCost Auto +Keyword Property CWCampImperial Auto +Keyword Property CWCampSons Auto +Keyword Property CWCapital Auto + + +keyword Property CWResetGarrisonStart1 Auto +keyword Property CWResetGarrisonStart2 Auto +keyword Property CWResetGarrisonStart3 Auto +keyword Property CWResetGarrisonStart4 Auto +keyword Property CWResetGarrisonStart5 Auto +keyword Property CWResetGarrisonStart6 Auto +keyword Property CWResetGarrisonStart7 Auto +keyword Property CWResetGarrisonStart8 Auto + +keyword Property CWAttackCityStart Auto +keyword Property CWEscapeCityStart Auto +keyword Property CWPrepareCityStart Auto + +keyword Property CW1PrioritySpawn Auto ;for use with CWReinforcementControllerScript +keyword Property CW2PrioritySpawn Auto ;for use with CWReinforcementControllerScript +keyword Property CW3PrioritySpawn Auto ;for use with CWReinforcementControllerScript +keyword Property CW4PrioritySpawn Auto ;for use with CWReinforcementControllerScript +keyword Property CW5PrioritySpawn Auto ;for use with CWReinforcementControllerScript + +keyword Property CW1ForcedSpawn Auto ;for use with CWReinforcementControllerScript +keyword Property CW2ForcedSpawn Auto ;for use with CWReinforcementControllerScript +keyword Property CW3ForcedSpawn Auto ;for use with CWReinforcementControllerScript +keyword Property CW4ForcedSpawn Auto ;for use with CWReinforcementControllerScript +keyword Property CW5ForcedSpawn Auto ;for use with CWReinforcementControllerScript + +Keyword Property LocTypeCity Auto +Keyword Property CWSiegeStart Auto +Keyword Property CWSiegeRunning Auto +Keyword Property CWFortSiegeSpecialStart Auto +Keyword Property CWFinaleStart Auto +Keyword Property CWFortSiegeMinorCapitalStart Auto + +Keyword Property CWResolution01Start Auto ;OBSOLETE +Keyword Property CWResolution02Start Auto ;OBSOLETE + +Keyword Property CWCitizensFleeStart Auto + +Keyword Property CWEventHappening Auto + +;## LocationRefTypes ## +LocationRefType Property CWSoldier Auto + +LocationRefType Property CWResolutionJarlMarker Auto ;used to find markers in CWAttackCity resolution quest to place Jarl, House carl, and body guards to meet the player's attempt to surrender +LocationRefType Property CWResolutionHouseCarlMarker Auto ;used to find markers in CWAttackCity resolution quest to place Jarl, House carl, and body guards to meet the player's attempt to surrender +LocationRefType Property CWResolutionJarlGuardMarker Auto ;used to find markers in CWAttackCity resolution quest to place Jarl, House carl, and body guards to meet the player's attempt to surrender + + +;## Messages ## + +;OBSOLETE: +Message Property CWCampaignWonFalkreathImperials Auto +Message Property CWCampaignWonFalkreathSons Auto +Message Property CWCampaignWonHjaalmarchImperials Auto +Message Property CWCampaignWonHjaalmarchSons Auto +Message Property CWCampaignWonPaleImperials Auto +Message Property CWCampaignWonPaleSons Auto +Message Property CWCampaignWonReachImperials Auto +Message Property CWCampaignWonReachSons Auto +Message Property CWCampaignWonRiftImperials Auto +Message Property CWCampaignWonRiftSons Auto +Message Property CWCampaignWonWhiterunImperials Auto +Message Property CWCampaignWonWhiterunSons Auto +Message Property CWCampaignWonWinterholdImperials Auto +Message Property CWCampaignWonWinterholdSons Auto +;endOBSOLETE + +Message Property CWCampaignOutcomeLostAttackMsgImperial Auto +Message Property CWCampaignOutcomeLostAttackMsgSons Auto +Message Property CWCampaignOutcomeLostDefenseMsgImperial Auto +Message Property CWCampaignOutcomeLostDefenseMsgSons Auto +Message Property CWCampaignOutcomeWonAttackMsgImperial Auto +Message Property CWCampaignOutcomeWonAttackMsgSons Auto +Message Property CWCampaignOutcomeWonDefenseMsgImperial Auto +Message Property CWCampaignOutcomeWonDefenseMsgSons Auto + + +Message Property CWCampaignTruce Auto + +;################################ ----------- Events ----------- ################################ + +Event OnInit() ;I COULD SET THESE WHEN I DECLARE THE PROPERTIES HOWEVER, MANY OF THESE ARE "DEBUG SETTINGS" AND "GAME SETTINGS" SO I PREFER TO SET THEM ALL HERE +; debug.trace("CWScript OnInit()") + log("CWScript", "OnInit()") + + ;DEBUG MODE? + debugOn.value = 0 ;Global CWDebugOn, turns on warnings + + ;OBSOLETE + ;CWDebugForceAttacker.value = 0 ;2 = Sons ;forces an attacker regardless of coin toss and # of consecutive attacks + ;CWDebugForceHold.value = 0 ;4 = Whiterun ;forces a hold to picked to be contested... might be unforced if this results in a failure to pick the hold because it breaks the rules + ;debugAllowNonAdjacentHolds = 0; ;allows attacker to attack non-adjacent holds + ;debugForceOffscreenResult = 0 ;1 ;forces each campaign to process it's result immediately offscreen + ;debugDBTraces = 1 + ;debugStartingCampaignPhase = 1 ;4 = resolution phase ;the phase that the campaign starts in, for example, you could force the campaign to always start in the resolution phase if you need to test a resolution quest + ;note: setting this to 4 and doing two consecutive campaigns may break until "DeleteWhenAble()" becomes threaded because it won't be able to start the resolution quest because it might still be running. PCB (purge cell buffers) will get around the problem + ;setting these to 1 will cause the major holds to be winable offscreen immediately + ;playerJoinedCampaginReach = 0 + ;playerJoinedCampaginWhiterun = 0 + ;playerJoinedCampaginRift = 0 + + + ;debugSkipSetOwnerCalls = 0 ;skips set owner calls, causes campaign to start much faster, will break things and is for speeding up certain kinds of playtesting + + ;debugTreatCityCapitalsAsTowns = 0 ;1 ;NOTE: FUNCTIONALITY MIGHT NO LONGER WORK -- causes Cities such as Whiterun, to be considered towns and start minor hold resolution quests + + + ;More or less obsolete... not sure if I use these anywhere, so I'm keeping them just in case + MaxAttackDelta = 20 ;-20 is treated as max in the negative as well + resolutionAttackDeltaMultiplier = 1.5 + + ;set Hold ownership at the start of the game + OwnerHaafingar = 1 + OwnerReach = 1 + OwnerHjaalmarch = 1 + OwnerWhiterun = 1 + OwnerFalkreath = 1 + OwnerPale = 2 + OwnerWinterhold = 2 + OwnerEastmarch = 2 + OwnerRift = 2 + + setInitalOwnerKeywordDataOnly() ;sets CWOwner keyword data to the numbers above + + + ;Sets the CountHoldsImperial and CountHoldsSons properties and associated globals + setCountHoldProperties() + + ;OBSOLETE?? -- set Attack Strength Value each Hold grants an adjacent contested hold (used by setStrengthPoints()) + StrValueHaafingar = 5 + StrValueReach = 5 + StrValueHjaalmarch = 3 + StrValueWhiterun = 5 + StrValueFalkreath = 3 + StrValuePale = 3 + StrValueWinterhold = 3 + StrValueEastmarch = 5 + StrValueRift = 5 + + ;set costs associated with CWCost keyword data for garrisons + iCostNonContestable = 9999 + iCostFort = 9999 ;*** I've decided to make it impossible to start off owning the fort if you are attacking the hold. The defender will not always start with the fort regardless of the attack delta. Resist the urge to change this. CWFortSiege quest (the quest you get to attack/defend a fort) makes use of the CWReinforcementControllerScript system, which ASSUMES that the attacker is the same as CW.Attacker and the defender is the same as CW.Defender. If it was possible to own the fort and be the attacker of the hold, then the CWFortSiege quest will break because it will assume the wrong thing about who is attacking/defending. + iCostSmall = 1 + iCostMedium = 2 + iCostLarge = 3 + iCostPatrol = 1 + + ;OBSOLETE? MAYBE NOT? + ;I have a vague feeling I'm using the iCostNonContestable somewhere still, so I probably shouldn't comment out this function call + setInitialCosts();establish CWCost keyword values + + ;set player campaign salary + baseSalary = 100 + SalaryMultRank1 = 1.25 + SalaryMultRank2 = 1.5 + SalaryMultRank3 = 2.0 + SalaryMultRank4 = 3.0 + + + ;OBSOLETE? + ;used by CWHoldManagerScript attached to this quest + ;RegisterForUpdate(5) + + ;*** I'm commenting this out to prevent seeing the initial log spam generated by the CWReset quest. When I can trace to seperate logs I should turn this back on + ;Note: It's strictly not needed since the original state of the game should be set up with how the enable markers are set in the esm... however, it seems safer to do a once through in Script. + ;set up the original owners of all the holds + ;setInitialOwners() + + ;needed especially if we aren't calling setInitialOwners() + initializeFortOwnerKeywordData() + + ;this starts off overrun with Forsworn there's a quest that will add it back to the war + RemoveGarrisonFromWar(KolskeggrMineLocation) + + ;starts without guards for Main Quest + RemoveGarrisonFromWar(RiverwoodLocation) + + ;Forts start with enemies in them that need to be cleared out + RemoveGarrisonFromWar(FortHraggstadLocation) + RemoveGarrisonFromWar(FortSungardLocation) + RemoveGarrisonFromWar(FortSnowhawkLocation) + RemoveGarrisonFromWar(FortGreymoorLocation) + RemoveGarrisonFromWar(FortNeugradLocation) + RemoveGarrisonFromWar(FortDunstadLocation) + RemoveGarrisonFromWar(FortKastavLocation) + RemoveGarrisonFromWar(FortAmolLocation) + RemoveGarrisonFromWar(FortGreenWallLocation) + + EnemyFortsAddedBackToWar = False ;false by default, here as a reminder + + + + ;turn off dragon attacks at Whiterun city, will be turned back on after the siege + ;WIs.DisallowDragons(WhiterunLocation) + ;** NOW HAPPENS IN WIFunctions attached to WI quest, and we won't be turning it back on + + + init += 1 ;this should never be more than 1, if > 1 it means the OnInit() has run more than once unexpectedly +EndEvent + +;auto State WaitingToStartNewCampaign +; Event OnUpdate() +; log("CWScript", "State WaitingToStartNewCampaign OnUpdate()") +; +; if debugForceOffscreenResult == 1 && WarIsActive == 1 +; GoToState("StartingNewCampaignOffscreenMode") +; log("CWScript", "WaitingToStartNewCampaign, WarIsActive == 1 & CWCampaign.IsRunning() == False, going to state StartingNewCampaignOffscreenMode.") +; +; ;### START NEW CAMPAIGN +; StartNewCampaign() +; +; elseif WarIsActive == 1 +; if CWCampaign.IsRunning() == False +; GoToState("StartingNewCampaign") +; log("CWScript", "WaitingToStartNewCampaign, WarIsActive == 1 & CWCampaign.IsRunning() == False, going to state StartingNewCampaign.") +; +; ;### START NEW CAMPAIGN +; StartNewCampaign() +; +; EndIf +; +; Else +; log("CWScript", "WaitingToStartNewCampaign, WarIsActive == 0, keep waiting.") +; +; EndIf +; +; EndEvent +; +; +;EndState +; +;State StartingNewCampaign +; Event OnUpdate() +; if CWCampaign.IsRunning() == True +; GoToState("WaitingForCampaignToFinish") +; +; log("CWScript", "StartingNewCampaign, CWCampaign.isRunning == True, going to state WaitingForCampaignToFinish.") +; +; Else +; log("CWScript", "StartingNewCampaign, CWCampaign.isRunning == False, waiting for CWCampaign to start.") +; +; endif +; +; EndEvent +; +;EndState +; +;State StartingNewCampaignOffscreenMode +; Event OnUpdate() +; log("CWScript", "StartingNewCampaignOffscreenMode state OnUpdate() is doing nothing until StartNewCampaign() function call has called ResolveOffscreen() and that function call has finished.") +; +; +; EndEvent +; +;EndState +; +;State WaitingForCampaignToFinish +; Event OnUpdate() +; +; if CWCampaign.IsRunning() == False +; GoToState("WaitingToStartNewCampaign") +; +; log("CWScript", "WaitingForCampaignToFinish, CWCampaign.IsRunning() == False, going to state WaitingToStartNewCampaign.") +; +; +; +; Else +; log("CWScript", "WaitingForCampaignToFinish, CWCampaign.IsRunning() == True, waiting for CWCampaign quest to stop.") +; +; endif +; +; EndEvent +;EndState +; +; +;State ResolvingCampaignOffscreen +; Event OnUpdate() +; log("CWScript", "ResolvingCampaignOffscreen state OnUpdate() is doing nothing until ResolveOffscreen() function call has finished.") +; +; +; EndEvent +; +;EndState + + + + + + +;################################ ----------- FUNCTIONS ----------- ################################ + +function log(string fileName, string stringToPrint, int severity = 0, bool AlwaysPrintLog = false, bool AlwaysPrintToMainLog = false) Global +{Will print to main papyrus log and the specified file if CWDebugOn global is true, or optional pararms are true} + + bool success + int debugMode = (Game.GetForm(0X0003F7D2) as GlobalVariable).GetValue() as Int ;this is the CWDebugOn global variable in the ESM. + + ;print to specified log + if debugMode == 1 || AlwaysPrintLog + debug.OpenUserLog(fileName) + +; success = debug.traceUser(fileName, " " + stringToPrint, severity) + + if success == False +; debug.trace("CWScript WARNING: log() Failed to print to " + FileName + ": " + stringToPrint, 2) + EndIf + + EndIf + + ;print to main log + if debugMode == 1 || AlwaysPrintToMainLog +; debug.trace(fileName + "-> " + stringToPrint, severity) + EndIf + +EndFunction + + + +function AddCivilWarAchievment(int whichCivilWarAchivement, Location AssociatedLocation = None) +{1 = Join a side, 2 = Take a fort in Reach or Rift, 3 = Win the war} + + log("CWScript", "AddCivilWarAchievment(" + whichCivilWarAchivement + ")") + + if whichCivilWarAchivement == 1 ;JOIN A SIDE + Game.AddAchievement(21) + elseif whichCivilWarAchivement == 2 ;TAKE FORT IN REACH OR RIFT + if AssociatedLocation == FortSungardLocation || AssociatedLocation == FortGreenwallLocation + Game.AddAchievement(22) + EndIf + + elseif whichCivilWarAchivement == 3 ;WIN THE WAR + Game.AddAchievement(23) + EndIf + +EndFunction + + +;OBSOLETE - from when there was multiple campaigns running at the same time +function modObjectiveByEnemySoldierDeath(Actor DeadSoldier, int AmountToMod = 1, Location Hold = None) + log("CWScript", "modObjectiveByEnemySoldierDeath(" + DeadSoldier + ")") + + if IsPlayerInMyFaction(DeadSoldier) + log("CWScript", "modObjectiveByEnemySoldierDeath(" + DeadSoldier + ") is in same faction as player. Ignored.") + + Else + log("CWScript", "modObjectiveByEnemySoldierDeath(" + DeadSoldier + ") Will find the hold, mod the appropriate CWObjXXX, and update the approprirate objective") + + location myHold + + if Hold == None + myHold = GetMyCurrentHoldLocation(DeadSoldier) + + Else + MyHold = Hold + EndIf + + int myHoldID = GetHoldID(myHold) + GlobalVariable myCWObjGlobal = GetCWObjGlobal(myHoldID) + + modCWObjGlobal(myCWObjGlobal, AmountToMod) + + log("CWScript", "modObjectiveByEnemySoldierDeath(" + DeadSoldier + ") Calling updateObjective with the hold location found for " + DeadSoldier) + updateObjective(myHold) + + EndIf + +EndFunction + +;OBSOLETE - from when there was multiple campaigns running at the same time +function modObjectiveBySabotage(ResourceObjectScript ResourceObject, int AmountToMod = 5) + log("CWScript", "modObjectiveBySabotage(" + ResourceObject + ")") + + location myHold = GetMyCurrentHoldLocation(ResourceObject) + + if myHold.GetKeywordData(CWOwner) == PlayerAllegiance + log("CWScript", "modObjectiveBySabotage(" + ResourceObject + ") is in hold owned by faction the player is allied to. Ignored.") + + Else + log("CWScript", "modObjectiveBySabotage(" + ResourceObject + ") Will mod the appropriate CWObjXXX, and update the approprirate objective") + + + int myHoldID = GetHoldID(myHold) + GlobalVariable myCWObjGlobal = GetCWObjGlobal(myHoldID) + + modCWObjGlobal(myCWObjGlobal, AmountToMod) + + log("CWScript", "modObjectiveBySabotage(" + ResourceObject + ") Calling updateObjective with the hold location found for " + ResourceObject) + updateObjective(myHold) + + EndIf + +EndFunction + +;OBSOLETE - from when there was multiple campaigns running at the same time +function modObjectiveByMissionSuccess(Location HoldLocation, int AmountToMod = 25) + log("CWScript", "modObjectiveByMissionSuccess(" + HoldLocation + ", " + AmountToMod + ")") + + ;bailout if the hold is owned by the players Faction + ;this way you can still get missions in holds you control - we will try this, might not ship with it + if GetOwner(HoldLocation) == PlayerAllegiance + log("CWScript", "modObjectiveByMissionSuccess(" + HoldLocation + ") hold is owned by player's faction, bailing out before modding the objective") + Return + EndIf + + + int myHoldID = GetHoldID(HoldLocation) + GlobalVariable myCWObjGlobal = GetCWObjGlobal(myHoldID) + + modCWObjGlobal(myCWObjGlobal, AmountToMod) + + log("CWScript", "modObjectiveByMissionSuccess() Calling updateObjective(" + HoldLocation +")" ) + updateObjective(HoldLocation) + + +EndFunction + +;OBSOLETE - from when there was multiple campaigns running at the same time +function modCWObjGlobal(GlobalVariable GlobalToModify, float amountToAdd) + float CWObjVal = (GlobalToModify.GetValue() as int + amountToAdd) as int + + ;cap at 99% + + if CWObjVal > 99 + CWObjVal = 99.0 + EndIf + + log("CWScript", "modCWObjGlobal() Calling OBSOLETE NOT INCREMENTING GLOBAL()", 1 ) +; GlobalToModify.SetValue(CWObjVal) + +EndFunction + + +function completeCWObj(Location HoldWhoseObjectiveToComplete) + int myHoldID = GetHoldID(HoldWhoseObjectiveToComplete) + GlobalVariable myCWObjGlobal = GetCWObjGlobal(myHoldID) + + ;if this is the first Whiterun siege (we assume this because the whiterun siege is always the first one) + if WhiterunSiegeFinished == False + WhiterunSiegeFinished = True + displayFactionLeaderObjective() + + ;This is a little awkward, as it causes the objective to display for the first time completed + ;but it prevents the problem of getting the Whiterun Objective again in stage 4 of CW Script + myCWObjGlobal.setValue(100) + updateObjective(HoldWhoseObjectiveToComplete, MarkObjectiveComplete = True) + + else + myCWObjGlobal.setValue(100) + updateObjective(HoldWhoseObjectiveToComplete, MarkObjectiveComplete = True) + + EndIf + +EndFunction + +;OBSOLETE - from when there was multiple campaigns running at the same time +function failCWObj(Location HoldWhoseObjectiveToFail) + int myHoldID = GetHoldID(HoldWhoseObjectiveToFail) + GlobalVariable myCWObjGlobal = GetCWObjGlobal(myHoldID) + + ;if this is the first Whiterun siege (we assume this because the whiterun siege because that is always the first one) + if WhiterunSiegeFinished == False + WhiterunSiegeFinished = True + displayFactionLeaderObjective() + + else + updateObjective(HoldWhoseObjectiveToFail, FailObjective = True, GlobalToResetDueToFailure = myCWObjGlobal) + myCWObjGlobal.setValue(0) + updateObjective(HoldWhoseObjectiveToFail) + + EndIf + +EndFunction + + +function updateObjective(location HoldLocationWhoseObjectiveWeShouldUpdate, bool MarkObjectiveComplete = false, bool FailObjective = false, GlobalVariable GlobalToResetDueToFailure = None) +{This sets the global and flashes the objective for taking over the hold for the supplied location} + + if (PlayerInvolved == 1 && WarIsActive == 1) == false + log("CWScript", "updateObjective() PlayerInvolved or WarIsActive, is not 1, NOT updating the objective." ) + + Return + + EndIf + + + ;note: this works because in the CWObj quest are objectives with the following formula: + ;x0y where x is the number of the hold, and y is the number for the players Faction + + int HoldID = GetHoldID(HoldLocationWhoseObjectiveWeShouldUpdate) + + int Obj = 100 * HoldID + Obj += PlayerAllegiance + + if CWObj.IsObjectiveCompleted(Obj) + ;do nothing + + Else + + if MarkObjectiveComplete == True + CWObj.SetObjectiveCompleted(Obj) + displayFactionLeaderObjective() + + ElseIf FailObjective == True + + ;Fail it + CWObj.SetObjectiveFailed(Obj) + + ;reset the percentage to completion + GlobalToResetDueToFailure.SetValue(0) + + ;reshow it + CWObj.SetObjectiveFailed(Obj, True) + CWObj.SetObjectiveDisplayed(Obj, abDisplayed = true, abForce = true) + + displayFactionLeaderObjective() + + else + + CWObj.UpdateCurrentInstanceGlobal(GetCWObjGlobal(HoldID)) + CWObj.SetObjectiveDisplayed(Obj, abDisplayed = true, abForce = true) + + EndIf + endif + +EndFunction + + +function displayFactionLeaderObjective() + int talkToLeaderObj = 1000 + PlayerAllegiance ;objective 1001 / 1002 is Report to Tullius / Ulfric + + CWObj.setStage(1) ; for journal entry + + ;because i want this to recur every time you finish taking a hold, set it not to be complete, then display it again + CWObj.SetObjectiveCompleted(talkToLeaderObj, false) + CWObj.SetObjectiveDisplayed(talkToLeaderObj, abDisplayed = true, abForce = true) + + CWObj.SetActive() + +EndFunction + +function DisplayHoldObjective() +;THIS HANDLES THE NEW LINEAR STYLE CAMPAIGN OBJECTIVES + + log("CWScript", "DisplayHoldObjective()") + + + ;***THIS LOGIC MUST BE IDENTICAL TO THE STACK OF DIALOGUE IN THE CW DIALOGUE WHERE Tullis/Ulfric TELL YOU WHERE TO GO NEXT *** + if PlayerAllegiance == iImperials + if getOwner(PaleHoldLocation) != iImperials + CWObj.SetObjectiveDisplayed(100 * GetHoldID(PaleHoldLocation) + iImperials, abDisplayed = true, abForce = true) + + Elseif getOwner(RiftHoldLocation) != iImperials + CWObj.SetObjectiveDisplayed(100 * GetHoldID(RiftHoldLocation) + iImperials, abDisplayed = true, abForce = true) + + Elseif getOwner(WinterholdHoldLocation) != iImperials + CWObj.SetObjectiveDisplayed(100 * GetHoldID(WinterholdHoldLocation) + iImperials, abDisplayed = true, abForce = true) + + Elseif getOwner(HjaalmarchHoldLocation) != iImperials + CWObj.SetObjectiveDisplayed(100 * GetHoldID(HjaalmarchHoldLocation) + iImperials, abDisplayed = true, abForce = true) + + Elseif getOwner(FalkreathHoldLocation) != iImperials + CWObj.SetObjectiveDisplayed(100 * GetHoldID(FalkreathHoldLocation) + iImperials, abDisplayed = true, abForce = true) + + Elseif getOwner(ReachHoldLocation) != iImperials + CWObj.SetObjectiveDisplayed(100 * GetHoldID(ReachHoldLocation) + iImperials, abDisplayed = true, abForce = true) + + Elseif getOwner(EastmarchHoldLocation) != iImperials + CWObj.SetObjectiveDisplayed(100 * GetHoldID(EastmarchHoldLocation) + iImperials, abDisplayed = true, abForce = true) + + Else + + EndIf + + elseif PlayerAllegiance == iSons + + if getOwner(FalkreathHoldLocation) != iSons + CWObj.SetObjectiveDisplayed(100 * GetHoldID(FalkreathHoldLocation) + iSons, abDisplayed = true, abForce = true) + + Elseif getOwner(ReachHoldLocation) != iSons + CWObj.SetObjectiveDisplayed(100 * GetHoldID(ReachHoldLocation) + iSons, abDisplayed = true, abForce = true) + + Elseif getOwner(HjaalmarchHoldLocation) != iSons + CWObj.SetObjectiveDisplayed(100 * GetHoldID(HjaalmarchHoldLocation) + iSons, abDisplayed = true, abForce = true) + + Elseif getOwner(PaleHoldLocation) != iSons + CWObj.SetObjectiveDisplayed(100 * GetHoldID(PaleHoldLocation) + iSons, abDisplayed = true, abForce = true) + + Elseif getOwner(WinterholdHoldLocation) != iSons + CWObj.SetObjectiveDisplayed(100 * GetHoldID(WinterholdHoldLocation) + iSons, abDisplayed = true, abForce = true) + + Elseif getOwner(RiftHoldLocation) != iSons + CWObj.SetObjectiveDisplayed(100 * GetHoldID(RiftHoldLocation) + iSons, abDisplayed = true, abForce = true) + + Elseif getOwner(HaafingarHoldLocation) != iSons + CWObj.SetObjectiveDisplayed(100 * GetHoldID(HaafingarHoldLocation) + iSons, abDisplayed = true, abForce = true) + + Else + + EndIf + + + Else + + + EndIf + + CWObj.SetActive() + +EndFunction + + +string Function FactionName(int CWFaction) + if CWFaction == iImperials + return "Imperials" + + elseif CWFaction == iSons + return "Sons" + ElseIf CWFaction == iBothFactions + return "Both Factions" + + Else + return "unknown faction(" + CWFaction + ")" + EndIf + + +EndFunction + +string Function HoldName(int HoldNumber) +{Returns a string based on the HoldNumber. Corresponds with iWhiterun, iRift, etc. Not for use to display to player. Just for sending to debug traces where you have a number refering to a hold.} + + if HoldNumber == iHaafingar ;1 + return "Haafingar" + + elseif HoldNumber == iReach ;2 + return "Reach" + + elseif HoldNumber == iHjaalmarch ;3 + return "Hjaalmarch" + + elseif HoldNumber == iWhiterun ;4 + return "Whiterun" + + elseif HoldNumber == iFalkreath ;5 + return "Falkreath" + + elseif HoldNumber == iPale ;6 + return "Pale" + + elseif HoldNumber == iWinterhold ;7 + return "Winterhold" + + elseif HoldNumber == iEastmarch ;8 + return "Eastmarch" + + elseif HoldNumber == iRift ;9 + return "Rift" + Else + return "unknown hold" + EndIf + +EndFunction + + +faction Function getFaction(int FactionToReturn, bool ReturnNPCFaction = false) +{Takes an int and returns the appropriate faction (1 = Imperials, 2 = Sons), ReturnNPCFaction returns the NPC faction that makes them hostile to members of the opposite NPC faction} + if FactionToReturn == iImperials + if ReturnNPCFaction == false + return CWImperialFaction + else + return CWImperialFactionNPC + endif + + elseif FactionToReturn == iSons + if ReturnNPCFaction == false + return CWSonsFaction + else + return CWSonsFactionNPC + endif + + Else + return None + log("CWScript", " WARNING: getFaction() encountered an unknown FactionToReturn. Expected 1 or 2, got " + FactionToReturn, 2, true, True) + + EndIf + +EndFunction + +faction function getPlayerAllegianceFaction(bool ReturnNPCFaction = false) + return getFaction(PlayerAllegiance, ReturnNPCFaction) +EndFunction + +faction Function getPlayerAllegianceEnemyFaction(bool ReturnNPCFaction = false) + return getFaction(getOppositeFactionInt(PlayerAllegiance), ReturnNPCFaction) +EndFunction + +int Function getOppositeFactionInt(int FactionWhoseOppositeYouWant) + + int returnVal + + if FactionWhoseOppositeYouWant == iImperials + returnVal = iSons + + ElseIf FactionWhoseOppositeYouWant == iSons + returnVal = iImperials + Else + log("CWScript", " WARNING: getOppositeFactionInt() encountered an unknown FactionWhoseOppositeYouWant. Expected 1 or 2, got " + FactionWhoseOppositeYouWant, 2, True, True) + + EndIf + + return returnVal + +EndFunction + +Actor Function GetRikkeOrGalmar(int iFaction = -1) +{Returns Rikke if iFaction == 1, or Galmar if iFaction == 2, uses PlayerAllegiance if iFaction == -1 (default)} + + Log("CWScript", "GetRikkeOrGalmar(" + iFaction +")") + + Actor ReturnRef + + if iFaction == -1 + iFaction = PlayerAllegiance + EndIf + + if iFaction == 1 + ReturnRef = Rikke.GetActorReference() + elseif iFaction == 2 + ReturnRef = Galmar.GetActorReference() + Else + log("CWScript", " WARNING: GetRikkeOrGalmar() encountered an unknown iFaction. Expected 1 or 2, got " + iFaction, 2, True, True) + EndIf + + Log("CWScript", "GetRikkeOrGalmar() returning:" + ReturnRef) + + return returnRef + + + +EndFunction + +bool function CheckRikkeGalmarNotAtCampPackageLocationAndMoveIfNeeded(Actor ActorToCheck, Package PackageToCheck, Location LocationToCheck, ObjectReference MarkerToMoveTo) + Log("CWScript", "CheckRikkeGalmarNotAtCampPackageLocation(" + ActorToCheck + PackageToCheck + LocationToCheck +")") + + bool returnVal + + if ActorToCheck.GetCurrentPackage() == PackageToCheck && ActorToCheck.IsInLocation(LocationToCheck) == False + Log("CWScript", "CheckRikkeGalmarNotAtCampPackageLocation MOVING ACTOR and Returning TRUE because is in package but not in location" ) + ActorToCheck.MoveTo(MarkerToMoveTo) + returnVal = True + + Else + Log("CWScript", "CheckRikkeGalmarNotAtCampPackageLocation Returning FALSE because is either not in package, or in package and in location.") + returnVal = False + + EndIf + + return returnVal + +EndFunction + +Function MoveRikkeGalmarToCampIfNeeded(bool CheckIfUnloaded = False) +{Moves them to the proper camp if not already there and, if not in the same location as the player.} +;When called by Rikke/Galmar's OnUnload block, CheckIfUnloaded == false, when called by their OnPackageChange block it is True + + Log("CWScript", "MoveRikkeGalmarToCampIfNeeded()") + + if WarIsActive == 1 && GetStageDone(4) + + if PlayerAllegiance == iImperials + Log("CWScript", "MoveRikkeGalmarToCampIfNeeded() player is Imperial, checking Rikke") + + Actor RikkeActor = Rikke.GetActorReference() + Package CurrentPackage = RikkeActor.GetCurrentPackage() + + if CheckIfUnloaded + If RikkeActor.Is3DLoaded() + Log("CWScript", "MoveRikkeGalmarToCampIfNeeded() CheckIfUnloaded == true, and Rikke has 3D so skip this.") + return + EndIf + EndIf + + if CheckRikkeGalmarNotAtCampPackageLocationAndMoveIfNeeded(RikkeActor, CWRikkeAtCampPale, MilitaryCampPaleImperialLocation, CWFieldCOMapTableMarkerPaleCampImperial) + elseif CheckRikkeGalmarNotAtCampPackageLocationAndMoveIfNeeded(RikkeActor, CWRikkeAtCampRift, MilitaryCampRiftImperialLocation, CWFieldCOMapTableMarkerRiftCampImperial) + elseif CheckRikkeGalmarNotAtCampPackageLocationAndMoveIfNeeded(RikkeActor, CWRikkeAtCampWinterhold, MilitaryCampWinterholdImperialLocation, CWFieldCOMapTableMarkerWinterholdCampImperial) + elseif CheckRikkeGalmarNotAtCampPackageLocationAndMoveIfNeeded(RikkeActor, CWRikkeAtCampHjaalmarch, MilitaryCampHjaalmarchImperialLocation, CWFieldCOMapTableMarkerHjaalmarchCampImperial) + elseif CheckRikkeGalmarNotAtCampPackageLocationAndMoveIfNeeded(RikkeActor, CWRikkeAtCampFalkreath, MilitaryCampFalkreathImperialLocation, CWFieldCOMapTableMarkerFalkreathCampImperial) + elseif CheckRikkeGalmarNotAtCampPackageLocationAndMoveIfNeeded(RikkeActor, CWRikkeAtCampReach, MilitaryCampReachImperialLocation, CWFieldCOMapTableMarkerReachCampImperial) + elseif CheckRikkeGalmarNotAtCampPackageLocationAndMoveIfNeeded(RikkeActor, CWRikkeAtCampEastmarch, MilitaryCampEastmarchImperialLocation, CWFieldCOMapTableMarkerEastmarchCampImperial) + EndIf + + + elseif PlayerAllegiance == iSons + Log("CWScript", "MoveRikkeGalmarToCampIfNeeded() player is Sons, checking Galmar") + + Actor GalmarActor = Galmar.GetActorReference() + Package CurrentPackage = GalmarActor.GetCurrentPackage() + + if CheckIfUnloaded + If GalmarActor.Is3DLoaded() + Log("CWScript", "MoveGalmarGalmarToCampIfNeeded() CheckIfUnloaded == true, and Galmar has 3D so skip this.") + return + EndIf + EndIf + + Log("CWScript", "MoveGalmarGalmarToCampIfNeeded() calling EvaluatePackage() on Galmar") + GalmarActor.EvaluatePackage() + + if CheckRikkeGalmarNotAtCampPackageLocationAndMoveIfNeeded(GalmarActor, CWGalmarAtCampFalkreath, MilitaryCampFalkreathSonsLocation, CWFieldCOMapTableMarkerFalkreathCampSons) + elseif CheckRikkeGalmarNotAtCampPackageLocationAndMoveIfNeeded(GalmarActor, CWGalmarAtCampReach, MilitaryCampReachSonsLocation, CWFieldCOMapTableMarkerReachCampSons) + elseif CheckRikkeGalmarNotAtCampPackageLocationAndMoveIfNeeded(GalmarActor, CWGalmarAtCampHjaalmarch, MilitaryCampHjaalmarchSonsLocation, CWFieldCOMapTableMarkerHjaalmarchCampSons) + elseif CheckRikkeGalmarNotAtCampPackageLocationAndMoveIfNeeded(GalmarActor, CWGalmarAtCampPale, MilitaryCampPaleSonsLocation, CWFieldCOMapTableMarkerPaleCampSons) + elseif CheckRikkeGalmarNotAtCampPackageLocationAndMoveIfNeeded(GalmarActor, CWGalmarAtCampWinterhold, MilitaryCampWinterholdSonsLocation, CWFieldCOMapTableMarkerWinterholdCampSons) + elseif CheckRikkeGalmarNotAtCampPackageLocationAndMoveIfNeeded(GalmarActor, CWGalmarAtCampRift, MilitaryCampRiftSonsLocation, CWFieldCOMapTableMarkerRiftCampSons) + elseif CheckRikkeGalmarNotAtCampPackageLocationAndMoveIfNeeded(GalmarActor, CWGalmarAtCampHaafingar, MilitaryCampHaafingarSonsLocation, CWFieldCOMapTableMarkerHaafingarCampSons) + EndIf + + Else + Log("CWScript", "MoveRikkeGalmarToCampIfNeeded() player is Neither Imperial nor Sons, not checking Rikke or Galmar") + + EndIf + + Else + + Log("CWScript", "MoveRikkeGalmarToCampIfNeeded() WarIsActive == false or GetStageDone(4) == false, not checking.") + + EndIf + + + +EndFunction + + + +GlobalVariable Function GetCWObjGlobal(int HoldNumber) +{Returns a string based on the HoldNumber. Corresponds with iWhiterun, iRift, etc. Not for use to display to player. Just for sending to debug traces where you have a number refering to a hold.} + + if HoldNumber == iHaafingar ;1 + return CWObjHaafingar + + elseif HoldNumber == iReach ;2 + return CWObjReach + + elseif HoldNumber == iHjaalmarch ;3 + return CWObjHjaalmarch + + elseif HoldNumber == iWhiterun ;4 + return CWObjWhiterun + + elseif HoldNumber == iFalkreath ;5 + return CWObjFalkreath + + elseif HoldNumber == iPale ;6 + return CWObjPale + + elseif HoldNumber == iWinterhold ;7 + return CWObjWinterhold + + elseif HoldNumber == iEastmarch ;8 + return CWObjEastmarch + + elseif HoldNumber == iRift ;9 + return CWObjRift + EndIf + +EndFunction + + +int Function GetActorAllgeiance(Actor ActorToCheck) +{Returns an integer correlating to the Civil War faction the actor belongs 1 = in faction CWImperialFaction, 2 = in faction CWSonsFaction} + + if ActorToCheck.IsInFaction(CWImperialFaction) || ActorToCheck.IsInFaction(GovImperial) + return iImperials + + ElseIf ActorToCheck.IsInFaction(CWSonsFaction) || ActorToCheck.IsInFaction(GovSons) + return iSons + + Else + log("CWScript", "GetActorAllgeiance() ActorToCheck(" + ActorToCheck + ") is neither in CWImperialFaction nor CWImperialFaction.", 1) + return -1 + + EndIf + +EndFunction + +bool function isImperial(Actor ActorToCheck) + return GetActorAllgeiance(ActorToCheck) == iImperials + +EndFunction + +bool function isSons(Actor ActorToCheck) + return GetActorAllgeiance(ActorToCheck) == iSons + +EndFunction + +bool function IsPlayerInMyFaction(Actor ActorToCheck) +{Returns true if the actor is in the same CWFaction as the player} + log("CWScript", "IsPlayerInMyFaction() ActorToCheck(" + ActorToCheck + ")") + + bool returnVal = GetActorAllgeiance(ActorToCheck) == GetActorAllgeiance(Game.GetPlayer()) + + log("CWScript", "IsPlayerInMyFaction() returning: " + returnVal) + + return returnVal + +EndFunction + + +Function SetPlayerAllegiance(int FactionToJoin, int MakePlayerInvolved = 0) +{Takes an int for which faction the player should join. 1 = Imperials, 2 = Sons. Swaps player in/out of factions, and sets the playerInvolved flag if the optional parameter is set to 1, and PlayerAllegiance properties.} + + ;set quest properies + playerInvolved = MakePlayerInvolved + playerAllegiance = FactionToJoin + CWPlayerAllegiance.value = FactionToJoin + + if FactionToJoin == iImperials + ;swap factions + Game.GetPlayer().AddToFaction(getFaction(iImperials)) + Game.GetPlayer().RemoveFromFaction(getFaction(iSons)) + + ;swap FactionLeader alias + AliasFactionLeader.ForceRefTo(AliasTullius.GetReference()) + + elseif FactionToJoin == iSons + Game.GetPlayer().AddToFaction(getFaction(iSons)) + Game.GetPlayer().RemoveFromFaction(getFaction(iImperials)) + + ;swap FactionLeader alias + AliasFactionLeader.ForceRefTo(AliasUlfric.GetReference()) + Else + log("CWScript", "SetPlayerAllegiance() encountered an unknown FactionToJoin. Expect 1 or 2, got " + FactionToJoin) + EndIf + + log("CWScript", "SetPlayerAllegiance() setting players allegiance to " + FactionToJoin + "(" + FactionName(FactionToJoin) + ")") + +EndFunction + + +function pacifyAliasForSurrender(ReferenceAlias RefAliasToPacify) + + ;MAKE SURE YOU PUT THE PLAYER in CWSurrenderTemporaryAllies BEFORE YOU CALL THIS + + log("CWScript", "pacifyAliasForSurrender(" + RefAliasToPacify + ")") + + Actor ActorRef = RefAliasToPacify.GetActorReference() + ClearActorsEnemyFlagOnCrimeFactions(ActorRef) + ActorRef.AddToFaction(CWSurrenderTemporaryAllies) + ActorRef.StopCombatAlarm() + Game.GetPlayer().StopCombatAlarm() + ActorRef.StopCombat() + +EndFunction + + +function ClearAliasEnemyFlagOnCrimeFactions(ReferenceAlias AliasWhoseCrimeFactionShouldClearPlayerEnemyFlag) + log("CWScript", "ClearActorsEnemyFlagOnCrimeFactions(" + AliasWhoseCrimeFactionShouldClearPlayerEnemyFlag + ") will call ClearActorsEnemyFlagOnCrimeFactions()") + + ClearActorsEnemyFlagOnCrimeFactions(AliasWhoseCrimeFactionShouldClearPlayerEnemyFlag.GetActorReference()) + +EndFunction + + +function ClearActorsEnemyFlagOnCrimeFactions(Actor ActorWhoseCrimeFactionShouldClearPlayerEnemyFlag) + Faction myCrimeFaction = ActorWhoseCrimeFactionShouldClearPlayerEnemyFlag.GetCrimeFaction() + + log("CWScript", "ClearActorsEnemyFlagOnCrimeFactions(" + ActorWhoseCrimeFactionShouldClearPlayerEnemyFlag + ") clearing player enemy flag on faction: " + myCrimeFaction ) + + if myCrimeFaction + myCrimeFaction.SetPlayerEnemy(false) + EndIf + +EndFunction + + + + + +Function PlayerTookOath(int iFaction) + log("CWScript", "PlayerTookOath(" + iFaction + ")") + + if iFaction == iImperials + CW00A.setObjectiveCompleted(1) + + CW00B.setObjectiveFailed(2) + CW01B.setStage(999) + + + elseif iFaction == iSons + CW00B.setObjectiveCompleted(2) + + CW00A.setObjectiveFailed(1) + CW01A.setStage(999) + + EndIf + + + ;turn off introductory quests: + CW00A.stop() + CW00B.stop() + + +EndFunction + + +Location Function GetMyCurrentHoldLocation(ObjectReference RefToGetCurrentHoldFor) +{Returns a location corresponding to the location of the hold the actor is currently in} + + Location returnLocation + + if RefToGetCurrentHoldFor.IsInLocation(HaafingarHoldLocation) + returnLocation = HaafingarHoldLocation + + Elseif RefToGetCurrentHoldFor.IsInLocation(ReachHoldLocation) + returnLocation = ReachHoldLocation + + Elseif RefToGetCurrentHoldFor.IsInLocation(HjaalmarchHoldLocation) + returnLocation = HjaalmarchHoldLocation + + Elseif RefToGetCurrentHoldFor.IsInLocation(WhiterunHoldLocation) + returnLocation = WhiterunHoldLocation + + Elseif RefToGetCurrentHoldFor.IsInLocation(FalkreathHoldLocation) + returnLocation = FalkreathHoldLocation + + Elseif RefToGetCurrentHoldFor.IsInLocation(PaleHoldLocation) + returnLocation = PaleHoldLocation + + Elseif RefToGetCurrentHoldFor.IsInLocation(WinterholdHoldLocation) + returnLocation = WinterholdHoldLocation + + Elseif RefToGetCurrentHoldFor.IsInLocation(EastmarchHoldLocation) + returnLocation = EastmarchHoldLocation + + Elseif RefToGetCurrentHoldFor.IsInLocation(RiftHoldLocation) + returnLocation = RiftHoldLocation + + Else + + log("CWScript", " WARNING: GetMyCurrentHoldLocation(" + RefToGetCurrentHoldFor + ") could NOT find the actor is in any hold location.", 2, true, true) + + EndIf + + log("CWScript", "GetMyCurrentHoldLocation(" + RefToGetCurrentHoldFor + ") RETURNING: " + returnLocation) + + return returnLocation + + +EndFunction + +Location Function GetMyEditorLocationHoldLocation(ObjectReference RefToGetEditorLocHoldFor) +{Returns a location corresponding to the location of the hold the actor's editor location currently in} + + Location EditorLocation = RefToGetEditorLocHoldFor.GetEditorLocation() + Location returnLocation + + If HaafingarHoldLocation.IsChild(EditorLocation) + returnLocation = HaafingarHoldLocation + + ElseIf ReachHoldLocation.IsChild(EditorLocation) + returnLocation = ReachHoldLocation + + ElseIf HjaalmarchHoldLocation.IsChild(EditorLocation) + returnLocation = HjaalmarchHoldLocation + + ElseIf WhiterunHoldLocation.IsChild(EditorLocation) + returnLocation = WhiterunHoldLocation + + ElseIf FalkreathHoldLocation.IsChild(EditorLocation) + returnLocation = FalkreathHoldLocation + + ElseIf PaleHoldLocation.IsChild(EditorLocation) + returnLocation = PaleHoldLocation + + ElseIf WinterholdHoldLocation.IsChild(EditorLocation) + returnLocation = WinterholdHoldLocation + + ElseIf EastmarchHoldLocation.IsChild(EditorLocation) + returnLocation = EastmarchHoldLocation + + ElseIf RiftHoldLocation.IsChild(EditorLocation) + returnLocation = RiftHoldLocation + + Else + + log("CWScript", " WARNING: GetMyEditorLocationHoldLocation(" + RefToGetEditorLocHoldFor + ") could NOT find the actor's editor location is in any hold location.", 2, true, true) + + EndIf + + log("CWScript", "GetMyEditorLocationHoldLocation(" + RefToGetEditorLocHoldFor + ") RETURNING: " + returnLocation) + + return returnLocation + + +EndFunction + + +Faction function GetCrimeFactionForActorFaction(Actor ActorToCheck) + + log("CWScript", "GetCrimeFactionForActorFaction(" + ActorToCheck + ") will GetActorAllgeiance() and the return crime faction based on what was returned") + + int myAllegiance = GetActorAllgeiance(ActorToCheck) + + Faction returnFaction + + if myAllegiance == iImperials + returnFaction = CrimeFactionImperial + + elseif myAllegiance == iSons + returnFaction = CrimeFactionSons + + Else + log("CWScript", " WARNING: GetCrimeFactionForActorFaction(" + ActorToCheck + ") is neither Imperial nor Sons, returning NONE)" , 2, true, true) + + EndIf + + log("CWScript", "GetCrimeFactionForActorFaction(" + ActorToCheck + ") returning:" + returnFaction) + + return returnFaction + +EndFunction + +Faction Function GetCrimeFactionForHold(Location HoldLocation) + {Returns the normal crime faction for the hold} + + log("CWScript", "GetCrimeFactionForHold(" + HoldLocation + ")") + + Faction ReturnFaction + + If HoldLocation == HaafingarHoldLocation + returnFaction = CrimeFactionHaafingar + ElseIf HoldLocation == ReachHoldLocation + returnFaction = CrimeFactionReach + ElseIf HoldLocation == HjaalmarchHoldLocation + returnFaction = CrimeFactionHjaalmarch + ElseIf HoldLocation == WhiterunHoldLocation + returnFaction = CrimeFactionWhiterun + ElseIf HoldLocation == FalkreathHoldLocation + returnFaction = CrimeFactionFalkreath + ElseIf HoldLocation == PaleHoldLocation + returnFaction = CrimeFactionPale + ElseIf HoldLocation == WinterholdHoldLocation + returnFaction = CrimeFactionWinterhold + ElseIf HoldLocation == EastmarchHoldLocation + returnFaction = CrimeFactionEastmarch + ElseIf HoldLocation == RiftHoldLocation + returnFaction = CrimeFactionRift + + Else + + log("CWScript", " WARNING: GetCrimeFactionForHold(" + HoldLocation + ") found an unexpected location that isn't a known hold.", 2, true, true) + + EndIf + + log("CWScript", "GetCrimeFactionForHold(" + HoldLocation + ") RETURNING: " + ReturnFaction) + + return ReturnFaction + +EndFunction + +function ClearHoldCrimeGold(Location HoldLocation) + + log("CWScript", "ClearHoldCrimeGold(" + HoldLocation + ") clearing crime gold.") + + faction crimeFaction = GetCrimeFactionForHold(HoldLocation) + + crimeFaction.SetCrimeGold(0) + crimeFaction.SetCrimeGoldViolent (0) + + +EndFunction + +function setCrimeFactionOnActorForEditorLocationsHold(Actor ActorToSetCrimeFaction) +{Finds the hold of the actor's editor location, then adds and sets the appropriate crime faction} + + log("CWScript", "setCrimeFactionOnActorForEditorLocationsHold(" + ActorToSetCrimeFaction + ")") + + Location myHold = GetMyEditorLocationHoldLocation(ActorToSetCrimeFaction) + Faction myCrimeFaction = GetCrimeFactionForHold(myHold) + + log("CWScript", "setCrimeFactionOnActorForEditorLocationsHold(" + ActorToSetCrimeFaction + ") will set crime faction to be " + myCrimeFaction) + + ActorToSetCrimeFaction.SetCrimeFaction(myCrimeFaction) + +EndFunction + +function DetermineAndSetCrimeFactionForSoldierActor(Actor ActorRef) + + log("CWScript", "DetermineAndSetCrimeFactionForSoldierActor(" + ActorRef + ") will determine my hold.") + + Location myHold = GetMyEditorLocationHoldLocation(ActorRef) + + log("CWScript", "DetermineAndSetCrimeFactionForSoldierActor(" + ActorRef + ") myHold = " + myHold + " now will determine if I am a defender or attacker and get my crime faction.") + + faction myCrimeFaction + + ;DON'T SET CRIME FACTION FOR FORT SOLDIERS ANY MORE + location ActorLocation = ActorRef.GetEditorLocation() + if ActorLocation.HasKeyword(CWFort) + log("CWScript", "DetermineAndSetCrimeFactionForSoldierActor(" + ActorRef + ") location is a CWFort, NOT CHANGING CRIME FACTION. Location: " + ActorLocation) + RETURN + endif + + + if IsActorDefender(ActorRef, myHold) + myCrimeFaction = GetCrimeFactionForHold(myHold) + + ElseIf IsActorAttacker(ActorRef, myHold) + myCrimeFaction = GetCrimeFactionForActorFaction(ActorRef) + + Else + log("CWScript", " WARNING: ActorRef is neither attacker nor defender!!! DetermineAndSetCrimeFactionForSoldierActor(" + ActorRef + ")", 2, true, true) + + EndIf + + log("CWScript", "DetermineAndSetCrimeFactionForSoldierActor(" + ActorRef + ") will set crime faction to: " + myCrimeFaction) + + ActorRef.SetCrimeFaction(myCrimeFaction) + + log("CWScript", "DetermineAndSetCrimeFactionForSoldierActor(" + ActorRef + ") double checking GetCrimeFaction():" + ActorRef.GetCrimeFaction()) + +EndFunction + +Location Function GetMyParentHoldLocation(Location LocationToGetParentHoldFor) +{Returns a location corresponding to the location of the hold the actor is currently in} + + Location returnLocation + + If HaafingarHoldLocation.IsChild(LocationToGetParentHoldFor) + returnLocation = HaafingarHoldLocation + + ElseIf ReachHoldLocation.IsChild(LocationToGetParentHoldFor) + returnLocation = ReachHoldLocation + + ElseIf HjaalmarchHoldLocation.IsChild(LocationToGetParentHoldFor) + returnLocation = HjaalmarchHoldLocation + + ElseIf WhiterunHoldLocation.IsChild(LocationToGetParentHoldFor) + returnLocation = WhiterunHoldLocation + + ElseIf FalkreathHoldLocation.IsChild(LocationToGetParentHoldFor) + returnLocation = FalkreathHoldLocation + + ElseIf PaleHoldLocation.IsChild(LocationToGetParentHoldFor) + returnLocation = PaleHoldLocation + + ElseIf WinterholdHoldLocation.IsChild(LocationToGetParentHoldFor) + returnLocation = WinterholdHoldLocation + + ElseIf EastmarchHoldLocation.IsChild(LocationToGetParentHoldFor) + returnLocation = EastmarchHoldLocation + + ElseIf RiftHoldLocation.IsChild(LocationToGetParentHoldFor) + returnLocation = RiftHoldLocation + + Else + + log("CWScript", " WARNING: GetMyParentHoldLocation(" + LocationToGetParentHoldFor + ") could NOT find the actor's editor location is in any hold location.", 2, true, true) + + EndIf + + log("CWScript", "GetMyParentHoldLocation(" + LocationToGetParentHoldFor + ") RETURNING: " + returnLocation) + + return returnLocation + +EndFunction + + + +Location Function GetCapitalLocationForHold(Location HoldLocation) +{Returns a location corresponding to the capital location of the hold location} + + Location returnLocation + + if HoldLocation == HaafingarHoldLocation + returnLocation = SolitudeLocation + + elseif HoldLocation == ReachHoldLocation + returnLocation = MarkarthLocation + + elseif HoldLocation == HjaalmarchHoldLocation + returnLocation = MorthalLocation + + elseif HoldLocation == WhiterunHoldLocation + returnLocation = WhiterunLocation + + elseif HoldLocation == FalkreathHoldLocation + returnLocation = FalkreathLocation + + elseif HoldLocation == PaleHoldLocation + returnLocation = DawnstarLocation + + elseif HoldLocation == WinterholdHoldLocation + returnLocation = WinterholdLocation + + elseif HoldLocation == EastmarchHoldLocation + returnLocation = WindhelmLocation + + elseif HoldLocation == RiftHoldLocation + returnLocation = RiftenLocation + + EndIf + + log("CWScript", "GetCapitalLocationForHold(" + HoldLocation + ") RETURNING: " + returnLocation) + + return returnLocation + +EndFunction + +location function GetCampLocationForHold(Location Hold, int GetCampForThisFaction) + + location ReturnVal + + if Hold == HaafingarHoldLocation + if GetCampForThisFaction == iImperials + ; returnVal = MilitaryCampHaafingarImperialLocation + Else + returnVal = MilitaryCampHaafingarSonsLocation + EndIf + + elseif Hold == ReachHoldLocation + if GetCampForThisFaction == iImperials + returnVal = MilitaryCampReachImperialLocation + Else + returnVal = MilitaryCampReachSonsLocation + endif + + elseif Hold == HjaalmarchHoldLocation + if GetCampForThisFaction == iImperials + returnVal = MilitaryCampHjaalmarchImperialLocation + Else + returnVal = MilitaryCampHjaalmarchSonsLocation + endif + + elseif Hold == WhiterunHoldLocation + if GetCampForThisFaction == iImperials + returnVal = MilitaryCampWhiterunImperialLocation + Else + returnVal = MilitaryCampWhiterunSonsLocation + endif + + elseif Hold == FalkreathHoldLocation + if GetCampForThisFaction == iImperials + returnVal = MilitaryCampFalkreathImperialLocation + Else + returnVal = MilitaryCampFalkreathSonsLocation + endif + + elseif Hold == PaleHoldLocation + if GetCampForThisFaction == iImperials + returnVal = MilitaryCampPaleImperialLocation + Else + returnVal = MilitaryCampPaleSonsLocation + endif + + elseif Hold == WinterholdHoldLocation + if GetCampForThisFaction == iImperials + returnVal = MilitaryCampWinterholdImperialLocation + Else + returnVal = MilitaryCampWinterholdSonsLocation + endif + + elseif Hold == EastmarchHoldLocation + if GetCampForThisFaction == iImperials + returnVal = MilitaryCampEastmarchImperialLocation + Else + ; returnVal = MilitaryCampEastmarchSonsLocation + endif + + elseif Hold == RiftHoldLocation + if GetCampForThisFaction == iImperials + returnVal = MilitaryCampRiftImperialLocation + Else + returnVal = MilitaryCampRiftSonsLocation + endif + + EndIf + + return returnVal + +EndFunction + + +ObjectReference function GetReferenceHQFieldCOForHold(Location Hold, int FactionToCheck) + + log("CWScript", "GetReferenceHQFieldCOForHold(" + Hold + ") calling GetAliasHQFieldCOForHold()") + + ObjectReference returnVar = GetAliasHQFieldCOForHold(Hold, FactionToCheck).GetReference() + + log("CWScript", "GetReferenceHQFieldCOForHold(" + Hold + ") calling GetAliasHQFieldCOForHold() RETURN:" + returnVar) + + return returnVar + +EndFunction + +ObjectReference function GetReferenceCampFieldCOForHold(Location Hold, int FactionToCheck) + + log("CWScript", "GetReferenceCampFieldCOForHold(" + Hold + ") calling GetAliasCampFieldCOForHold()") + + ObjectReference returnVar = GetAliasCampFieldCOForHold(Hold, FactionToCheck).GetReference() + + log("CWScript", "GetReferenceCampFieldCOForHold(" + Hold + ") calling GetAliasCampFieldCOForHold() RETURN:" + returnVar) + + return returnVar + +EndFunction + +referenceAlias function GetAliasHQFieldCOForHold(Location Hold, int FactionToCheck) + + log("CWScript", "GetAliasHQFieldCOForHold(" + Hold + ")") + + ReferenceAlias returnVal + + if FactionToCheck == iImperials + + if Hold == EastmarchHoldLocation + returnVal = Alias_FieldCOImperialEastmarchHQ + elseif Hold == FalkreathHoldLocation + returnVal = Alias_FieldCOImperialFalkreathHQ + elseif Hold == HaafingarHoldLocation + returnVal = Alias_FieldCOImperialHaafingarHQ + elseif Hold == HjaalmarchHoldLocation + returnVal = Alias_FieldCOImperialHjaalmarchHQ + elseif Hold == PaleHoldLocation + returnVal = Alias_FieldCOImperialPaleHQ + elseif Hold == ReachHoldLocation + returnVal = Alias_FieldCOImperialReachHQ + elseif Hold == RiftHoldLocation + returnVal = Alias_FieldCOImperialRiftHQ + elseif Hold == WhiterunHoldLocation + returnVal = Alias_FieldCOImperialWhiterunHQ + elseif Hold == WinterholdHoldLocation + returnVal = Alias_FieldCOImperialWinterholdHQ + + EndIf + + elseif FactionToCheck == iSons + + if Hold == EastmarchHoldLocation + returnVal = Alias_FieldCOSonsEastmarchHQ + elseif Hold == FalkreathHoldLocation + returnVal = Alias_FieldCOSonsFalkreathHQ + elseif Hold == HaafingarHoldLocation + returnVal = Alias_FieldCOSonsHaafingarHQ + elseif Hold == HjaalmarchHoldLocation + returnVal = Alias_FieldCOSonsHjaalmarchHQ + elseif Hold == PaleHoldLocation + returnVal = Alias_FieldCOSonsPaleHQ + elseif Hold == ReachHoldLocation + returnVal = Alias_FieldCOSonsReachHQ + elseif Hold == RiftHoldLocation + returnVal = Alias_FieldCOSonsRiftHQ + elseif Hold == WhiterunHoldLocation + returnVal = Alias_FieldCOSonsWhiterunHQ + elseif Hold == WinterholdHoldLocation + returnVal = Alias_FieldCOSonsWinterholdHQ + + endif + + Else + log("CWScript", " WARNING: GetAliasHQFieldCOForHold(" + Hold + ") expect 1 or 2 for FactionToCheck, intead got: " + FactionToCheck, 2, true, true) + + endif + + log("CWScript", "GetAliasHQFieldCOForHold(" + Hold + ") RETURNING: " + returnVal) + + return returnVal + +EndFunction + +ReferenceAlias Function GetAliasCampFieldCOForHold(Location Hold, int FactionToCheck) + + log("CWScript", "GetAliasCampFieldCOForHold(" + Hold + ")") + + ReferenceAlias returnVal + + if FactionToCheck == iImperials + + if Hold == EastmarchHoldLocation + returnVal = Alias_FieldCOImperialEastmarchCamp + elseif Hold == FalkreathHoldLocation + returnVal = Alias_FieldCOImperialFalkreathCamp + elseif Hold == HaafingarHoldLocation + returnVal = Alias_FieldCOImperialHaafingarCamp + elseif Hold == HjaalmarchHoldLocation + returnVal = Alias_FieldCOImperialHjaalmarchCamp + elseif Hold == PaleHoldLocation + returnVal = Alias_FieldCOImperialPaleCamp + elseif Hold == ReachHoldLocation + returnVal = Alias_FieldCOImperialReachCamp + elseif Hold == RiftHoldLocation + returnVal = Alias_FieldCOImperialRiftCamp + elseif Hold == WhiterunHoldLocation + returnVal = Alias_FieldCOImperialWhiterunCamp + elseif Hold == WinterholdHoldLocation + returnVal = Alias_FieldCOImperialWinterholdCamp + + endif + + Elseif FactionToCheck == iSons + + if Hold == EastmarchHoldLocation + returnVal = Alias_FieldCOSonsEastmarchCamp + elseif Hold == FalkreathHoldLocation + returnVal = Alias_FieldCOSonsFalkreathCamp + elseif Hold == HaafingarHoldLocation + returnVal = Alias_FieldCOSonsHaafingarCamp + elseif Hold == HjaalmarchHoldLocation + returnVal = Alias_FieldCOSonsHjaalmarchCamp + elseif Hold == PaleHoldLocation + returnVal = Alias_FieldCOSonsPaleCamp + elseif Hold == ReachHoldLocation + returnVal = Alias_FieldCOSonsReachCamp + elseif Hold == RiftHoldLocation + returnVal = Alias_FieldCOSonsRiftCamp + elseif Hold == WhiterunHoldLocation + returnVal = Alias_FieldCOSonsWhiterunCamp + elseif Hold == WinterholdHoldLocation + returnVal = Alias_FieldCOSonsWinterholdCamp + + endif + + Else + log("CWScript", " WARNING: GetAliasCampFieldCOForHold(" + Hold + ") expect 1 or 2 for FactionToCheck, intead got: " + FactionToCheck, 2, true, true) + + EndIf + + log("CWScript", "GetAliasCampFieldCOForHold(" + Hold + ") RETURNING: " + returnVal) + + return returnVal + +EndFunction + +int Function GetHoldID(Location HoldToCheck) +{Returns an int specifying the ID of the specified hold; -1 = FAIL} + int holdID = -1 + + if HoldToCheck == HaafingarHoldLocation + holdID = iHaafingar ;1 + elseif HoldToCheck == ReachHoldLocation + holdID = iReach ;2 + elseif HoldToCheck == HjaalmarchHoldLocation + holdID = iHjaalmarch ;3 + elseif HoldToCheck == WhiterunHoldLocation + holdID = iWhiterun ;4 + elseif HoldToCheck == FalkreathHoldLocation + holdID = iFalkreath ;5 + elseif HoldToCheck == PaleHoldLocation + holdID = iPale ;6 + elseif HoldToCheck == WinterholdHoldLocation + holdID = iWinterhold ;7 + elseif HoldToCheck == EastmarchHoldLocation + holdID = iEastmarch ;8 + elseif HoldToCheck == RiftHoldLocation + holdID = iRift ;9 + else + log("CWScript", "GetHoldID(" + HoldToCheck + ") location unrecognized. Expected one of the nine holds, got something else.", 2) + holdID = -1 + + EndIf + + log("CWScript", "GetHoldID() HoldToCheck[" + HoldToCheck + "], ID = " + holdID) + + return holdID +EndFunction + + + +int Function GetHoldOwner(int HoldToCheck) +{Returns an int specifying current owner of HoldToCheck. 1 = Imperials, 2 = Sons, -1 = FAIL} + int owner ;1 = Imperials, 2 = Sons + if HoldToCheck == iHaafingar ;1 + owner = ownerHaafingar + elseif HoldToCheck == iReach ; 2 + owner = ownerReach + elseif HoldToCheck == iHjaalmarch ;3 + owner = ownerHjaalmarch + elseif HoldToCheck == iWhiterun ;4 + owner = ownerWhiterun + elseif HoldToCheck == iFalkreath ;5 + owner = ownerFalkreath + elseif HoldToCheck == iPale ;6 + owner = ownerPale + elseif HoldToCheck == iWinterhold ;7 + owner = ownerWinterhold + elseif HoldToCheck == iEastmarch ;8 + owner = ownerEastmarch + elseif HoldToCheck == iRift ;9 + owner = ownerRift + else + log("CWScript", "GetHoldOwner(" + HoldToCheck + ") parametered unrecognized. Expected an int 1-9 as HoldToCheck, got something else.", 2) + owner = -1 + EndIf + + log("CWScript", "GetHoldOwner() HoldToCheck[" + HoldToCheck + "], owner = " + owner + "[" + FactionName(owner) + "]") + + return owner +EndFunction + +bool function IsPlayerAttacking(Location LocationToCheck) + bool returnVal + + if LocationToCheck.GetKeywordData(CWOwner) == PlayerAllegiance + returnVal = False + + Else + returnVal = True + + EndIf + + log("CWScript", "IsPlayerAttacking(" + LocationToCheck + ") returning: " + returnVal) + + return returnVal + +EndFunction + + +function DiscoverMilitaryCampMarkers(int FactionID) + + if FactionID == iImperials + + ;MilitaryCampEastmarchImperialMapMarker NOT ADDING THIS HERE BECAUSE THIS FUNCTION HAPPENS BEFORE YOU ARE ALLOWED TO GET MISSIONS IN THE FINAL HOLD + MilitaryCampFalkreathImperialMapMarker.addToMap() + MilitaryCampHjaalmarchImperialMapMarker.addToMap() + MilitaryCampPaleImperialMapMarker.addToMap() + MilitaryCampReachImperialMapMarker.addToMap() + MilitaryCampRiftImperialMapMarker.addToMap() + MilitaryCampWhiterunImperialMapMarker.addToMap() + MilitaryCampWinterholdImperialMapMarker.addToMap() + + elseif FactionID == iSons + MilitaryCampFalkreathSonsMapMarker.addToMap() + ;MilitaryCampHaafingarSonsMapMarker NOT ADDING THIS HERE BECAUSE THIS FUNCTION HAPPENS BEFORE YOU ARE ALLOWED TO GET MISSIONS IN THE FINAL HOLD + MilitaryCampHjaalmarchSonsMapMarker.addToMap() + MilitaryCampPaleSonsMapMarker.addToMap() + MilitaryCampReachSonsMapMarker.addToMap() + MilitaryCampRiftSonsMapMarker.addToMap() + MilitaryCampWhiterunSonsMapMarker.addToMap() + MilitaryCampWinterholdSonsMapMarker.addToMap() + + Else + log("CWScript", " WARNING: DiscoverMilitaryCampMarkers(" + FactionID + ") FactionID parameter unrecognized. Expect 1 or 2. Got:" + FactionID, 2, True, True) + + EndIf + + +EndFunction + + +Bool Function FactionOwnsAll(int FactionToTest) +{Returns true if FactionToTest represents a faction that owns all the contestable holds.} + + ;Note the use of \ to break the single if statement across multiple lines for ease of reading + if GetHoldOwner(iReach) == FactionToTest && \ + GetHoldOwner(iHjaalmarch) == FactionToTest && \ + GetHoldOwner(iWhiterun) == FactionToTest && \ + GetHoldOwner(iFalkreath) == FactionToTest && \ + GetHoldOwner(iPale) == FactionToTest && \ + GetHoldOwner(iWinterhold) == FactionToTest && \ + GetHoldOwner(iRift) == FactionToTest + return True + Else + return False + EndIf + +EndFunction + +function RegisterEventHappening(Location LocationWhereEventIsHappening) +{set CWEventHappening keyword data to 1, this can be checked in conditions if designers want things to happen or not happen when civil war events are happening in their location} + + if LocationWhereEventIsHappening.HasKeyword(CWEventHappening) + log("CWScript", " RegisterEventHappening(" + LocationWhereEventIsHappening + ") setting CWEventHappening keyword data to 1.") + LocationWhereEventIsHappening.SetKeywordData(CWEventHappening, 1) + Else + log("CWScript", " WARNING: RegisterEventHappening(" + LocationWhereEventIsHappening + ") does not have CWEventHappening keyword", 2, True, True) + EndIf + +EndFunction + +function UnregisterEventHappening(Location LocationWhereEventIsHappening) +{set CWEventHappening keyword data to 1, this can be checked in conditions if designers want things to happen or not happen when civil war events are happening in their location} + + if LocationWhereEventIsHappening.HasKeyword(CWEventHappening) + log("CWScript", " RegisterEventHappening(" + LocationWhereEventIsHappening + ") setting CWEventHappening keyword data to 0.") + LocationWhereEventIsHappening.SetKeywordData(CWEventHappening, 0) + Else + log("CWScript", " WARNING: RegisterEventHappening(" + LocationWhereEventIsHappening + ") does not have CWEventHappening keyword", 2, True, True) + EndIf + +EndFunction + + +function stopSiegeQuests() + log("CWScript", "CW Script: stopSiegeQuests() NEED TO SHUT DOWN AND CLEAN UP SIEGE QUESTS", 1) + debug.messageBox("CW Script: stopSiegeQuests() NEED TO SHUT DOWN AND CLEAN UP SIEGE QUESTS") +EndFunction + +function StopCivilWar() ;called by CW STAGE 255 +{Used to cut a campaign short so the Civil War can halt for the peace treaty signing scenes} + WarIsActive = -1 + PlayerInvolved = 1 + + ;STOP ANY CIVIL WAR MISSION QUESTS / FORT BATTLES + if CWFortSiegeFort.IsRunning() + CWFortSiegeFort.setStage(9000) + + Rikke.GetActorReference().removeFromFaction(CWFieldCOActiveMissionFaction) + Galmar.GetActorReference().removeFromFaction(CWFieldCOActiveMissionFaction) + Rikke.GetActorReference().removeFromFaction(CWFieldCOSuccessfulMissionFaction) + Galmar.GetActorReference().removeFromFaction(CWFieldCOSuccessfulMissionFaction) + + EndIf + + if CWMission03.IsRunning() + CWMission03.setStage(200) + + Rikke.GetActorReference().removeFromFaction(CWFieldCOActiveMissionFaction) + Galmar.GetActorReference().removeFromFaction(CWFieldCOActiveMissionFaction) + Rikke.GetActorReference().removeFromFaction(CWFieldCOSuccessfulMissionFaction) + Galmar.GetActorReference().removeFromFaction(CWFieldCOSuccessfulMissionFaction) + EndIf + + if CWMission04.IsRunning() + CWMission04.setStage(200) + + Rikke.GetActorReference().removeFromFaction(CWFieldCOActiveMissionFaction) + Galmar.GetActorReference().removeFromFaction(CWFieldCOActiveMissionFaction) + Rikke.GetActorReference().removeFromFaction(CWFieldCOSuccessfulMissionFaction) + Galmar.GetActorReference().removeFromFaction(CWFieldCOSuccessfulMissionFaction) + EndIf + + if CWMission07.IsRunning() + CWMission07.setStage(200) + + Rikke.GetActorReference().removeFromFaction(CWFieldCOActiveMissionFaction) + Galmar.GetActorReference().removeFromFaction(CWFieldCOActiveMissionFaction) + Rikke.GetActorReference().removeFromFaction(CWFieldCOSuccessfulMissionFaction) + Galmar.GetActorReference().removeFromFaction(CWFieldCOSuccessfulMissionFaction) + EndIf + +; ;If player's side is attacking "FAIL" the CWCampaign, if player's side is defending "COMPLETE" the CWCampaign +; if playerAllegiance == Attacker +; CWCampaignObj.setStage(300) +; Else +; CWCampaignObj.setStage(200) +; EndIf +; +; CWCampaign.stop() +; +; (CWCampaign as CWCampaignScript).ResetCampaign() +; (CWCampaign as CWCampaignPollForMissionAcceptScript).StopPolling() +; setHoldOwner(ContestedHold, ownerContestedHold) + +; CWCampaignTruce.show() + +EndFunction + +function restartCivilWar() ;called in stage 256 of CW quest + SetStage(playerAllegiance) ;sets stage 1 or 2, which calls setplayeAllegience and sets PlayerInvolved to be 1 + + if getStageDone(4) ;makes sure the player has completed a campaign before setting warIsActive (in case you haven't finished the Whiterun battle yet) + WarIsActive = 1 + + Else + WarIsActive = 0 ;in case it was set to -1 due to peace treaty + + endif + +; restartCivilWarCompleteObjectiveIfNeeded(102, HaafingarHoldLocation) + restartCivilWarCompleteObjectiveIfNeeded(201, ReachHoldLocation) + restartCivilWarCompleteObjectiveIfNeeded(202, ReachHoldLocation) + restartCivilWarCompleteObjectiveIfNeeded(301, HjaalmarchHoldLocation) + restartCivilWarCompleteObjectiveIfNeeded(302, HjaalmarchHoldLocation) + restartCivilWarCompleteObjectiveIfNeeded(401, WhiterunHoldLocation) + restartCivilWarCompleteObjectiveIfNeeded(402, WhiterunHoldLocation) + restartCivilWarCompleteObjectiveIfNeeded(501, FalkreathHoldLocation) + restartCivilWarCompleteObjectiveIfNeeded(502, FalkreathHoldLocation) + restartCivilWarCompleteObjectiveIfNeeded(601, PaleHoldLocation) + restartCivilWarCompleteObjectiveIfNeeded(602, PaleHoldLocation) + restartCivilWarCompleteObjectiveIfNeeded(701, WinterholdHoldLocation) + restartCivilWarCompleteObjectiveIfNeeded(702, WinterholdHoldLocation) +; restartCivilWarCompleteObjectiveIfNeeded(801, Eastmarch HoldLocation) + restartCivilWarCompleteObjectiveIfNeeded(901, RiftHoldLocation) + restartCivilWarCompleteObjectiveIfNeeded(902, RiftHoldLocation) + + +EndFunction + +function restartCivilWarCompleteObjectiveIfNeeded(int objectiveToCheck, Location HoldLocationToCheck) + + bool ObjDisplayed = CWObj.IsObjectiveDisplayed(objectiveToCheck) + bool ObjCompleted = CWObj.IsObjectiveCompleted(objectiveToCheck) + bool HoldOwnedByPlayersFaction = HoldLocationToCheck.GetKeywordData(CWOwner) == playerAllegiance + + bool ShouldCompleteObj = False + + if ObjDisplayed && ObjCompleted == False + if HoldOwnedByPlayersFaction + ShouldCompleteObj = true + EndIf + EndIf + + log("CWScript", " restartCivilWarCompleteObjectiveIfNeeded() COMPLETE OBJECTIVE? " + ShouldCompleteObj + "; Details: Objective: " + objectiveToCheck + ", Location: " + HoldLocationToCheck + " Objective Displayed?: " + ObjDisplayed + ", Objective Completed?: " + ObjCompleted + ", Location Owned by Player's faction?: " + HoldOwnedByPlayersFaction) + + if ShouldCompleteObj + CWObj.SetObjectiveCompleted(objectiveToCheck) + EndIf + +EndFunction + + + +Function SetCountWins() +{Sets various count variables for keeping track of how many times each faction won each hold... calls SetCountWinsImperials() and SetCountWinsSons()} + + if ContestedHoldWinner == iImperials + SetCountWinsImperials() + Elseif contestedHoldWinner == iSons + SetCountWinsSons() + EndIf +EndFunction + + +Function SetCountWinsImperials() + CountWinImperials += 1 + + if ContestedHold == iReach ;2 + CountWinReachImperials += 1 + + elseif ContestedHold == iHjaalmarch ;3 + CountWinHjaalmarchImperials += 1 + + elseif ContestedHold == iWhiterun ;4 + CountWinWhiterunImperials += 1 + + elseif ContestedHold == iFalkreath ;5 + CountWinFalkreathImperials += 1 + + elseif ContestedHold == iPale ;6 + CountWinPaleImperials += 1 + + elseif ContestedHold == iWinterhold ;7 + CountWinWinterholdImperials += 1 + + elseif ContestedHold == iRift ;9 + CountWinRiftImperials += 1 + + EndIf +EndFunction + +Function SetCountWinsSons() + CountWinSons += 1 + + if ContestedHold == iReach ;2 + CountWinReachSons += 1 + + elseif ContestedHold == iHjaalmarch ;3 + CountWinHjaalmarchSons += 1 + + elseif ContestedHold == iWhiterun ;4 + CountWinWhiterunSons += 1 + + elseif ContestedHold == iFalkreath ;5 + CountWinFalkreathSons += 1 + + elseif ContestedHold == iPale ;6 + CountWinPaleSons += 1 + + elseif ContestedHold == iWinterhold ;7 + CountWinWinterholdSons += 1 + + elseif ContestedHold == iRift ;9 + CountWinRiftSons += 1 + + EndIf +EndFunction + + + +Message Function getCampaignWonMessage() +{Returns the message object associated with the corresponding contestedHold and contestedHoldWinner property} + + Message messageToReturn + + if PlayerAllegiance == iImperials + if contestedHoldWinner == iImperials + if contestedHoldWinType == 1 ;took away + messageToReturn = CWCampaignOutcomeWonAttackMsgImperial + elseif contestedHoldWinType == 2 ;held onto + messageToReturn = CWCampaignOutcomeWonDefenseMsgImperial + Else + Log("CWScript", " WARNING: getCampaignWonMessage() expected 1 or 2 for contestedHoldWinType, found: " + contestedHoldWinType, 2) + EndIf + + elseif contestedHoldWinner == iSons + if contestedHoldWinType == 1 ; Sons took away + messageToReturn = CWCampaignOutcomeLostDefenseMsgImperial + elseif contestedHoldWinType == 2 ;Sons held onto + messageToReturn = CWCampaignOutcomeLostAttackMsgImperial + Else + Log("CWScript", " WARNING: getCampaignWonMessage() expected 1 or 2 for contestedHoldWinType, found: " + contestedHoldWinType, 2) + EndIf + + Else + Log("CWScript", " WARNING: getCampaignWonMessage() expected 1 or 2 for contestedHoldWinner, found: " + contestedHoldWinType, 2) + + EndIf + + elseif PlayerAllegiance == iSons + if contestedHoldWinner == iSons + if contestedHoldWinType == 1 ;took away + messageToReturn = CWCampaignOutcomeWonAttackMsgSons + elseif contestedHoldWinType == 2 ;held onto + messageToReturn = CWCampaignOutcomeWonDefenseMsgSons + Else + Log("CWScript", " WARNING: getCampaignWonMessage() expected 1 or 2 for contestedHoldWinType, found: " + contestedHoldWinType, 2) + EndIf + + elseif contestedHoldWinner == iImperials + if contestedHoldWinType == 1 ; Imperials took away + messageToReturn = CWCampaignOutcomeLostDefenseMsgSons + elseif contestedHoldWinType == 2 ;Imperials held onto + messageToReturn = CWCampaignOutcomeLostAttackMsgSons + Else + Log("CWScript", " WARNING: getCampaignWonMessage() expected 1 or 2 for contestedHoldWinType, found: " + contestedHoldWinType, 2) + EndIf + + Else + Log("CWScript", " WARNING: getCampaignWonMessage() expected 1 or 2 for contestedHoldWinner, found: " + contestedHoldWinner, 2) + + EndIf + + Else + Log("CWScript", " WARNING: getCampaignWonMessage() expected 1 or 2 for PlayerAllegiance, found: " + PlayerAllegiance, 2) + + EndIf + + + Log("CWScript", "getCampaignWonMessage() returning: " + messageToReturn) + + return messageToReturn + + +; If contestedHold == iReach +; If contestedHoldWinner == iImperials +; return CWCampaignWonReachImperials +; Else ;== iSons +; return CWCampaignWonReachSons +; EndIf +; +; ElseIf contestedHold == iHjaalmarch +; If contestedHoldWinner == iImperials +; return CWCampaignWonHjaalmarchImperials +; Else ;== iSons +; return CWCampaignWonHjaalmarchSons +; EndIf +; +; ElseIf contestedHold == iWhiterun +; If contestedHoldWinner == iImperials +; return CWCampaignWonWhiterunImperials +; Else ;== iSons +; return CWCampaignWonWhiterunSons +; EndIf +; +; ElseIf contestedHold == iFalkreath +; If contestedHoldWinner == iImperials +; return CWCampaignWonFalkreathImperials +; Else ;== iSons +; return CWCampaignWonFalkreathSons +; EndIf +; +; ElseIf contestedHold == iPale +; If contestedHoldWinner == iImperials +; return CWCampaignWonPaleImperials +; Else ;== iSons +; return CWCampaignWonPaleSons +; EndIf +; +; ElseIf contestedHold == iWinterhold +; If contestedHoldWinner == iImperials +; return CWCampaignWonWinterholdImperials +; Else ;== iSons +; return CWCampaignWonWinterholdSons +; EndIf +; +; ElseIf contestedHold == iRift +; If contestedHoldWinner == iImperials +; return CWCampaignWonRiftImperials +; Else ;== iSons +; return CWCampaignWonRiftSons +; EndIf +; +; EndIf + +EndFunction + + +location Function getLocationForHold(int Hold) +{Returns a location corresponding to the integer Hold parameter} + + if Hold == iHaafingar ;1 + return HaafingarHoldLocation + + elseif Hold == iReach ;2 + return ReachHoldLocation + + elseif Hold == iHjaalmarch ;3 + return HjaalmarchHoldLocation + + elseif Hold == iWhiterun ;4 + return WhiterunHoldLocation + + elseif Hold == iFalkreath ;5 + return FalkreathHoldLocation + + elseif Hold == iPale ;6 + return PaleHoldLocation + + elseif Hold == iWinterhold ;7 + return WinterholdHoldLocation + + elseif Hold == iEastmarch ;8 + return EastmarchHoldLocation + + elseif Hold == iRift ;9 + return RiftHoldLocation + + EndIf + +EndFunction + +int function getIntForHoldLocation(Location LocationToGetIntFor) + + if LocationToGetIntFor == None + log("CWScript", " WARNING! getIntForHoldLocation() returning -1 because it recieved an unexpected location that isn't a hold: " + LocationToGetIntFor) + return -1 + EndIf + + + if LocationToGetIntFor == HaafingarHoldLocation + return iHaafingar + + ElseIf LocationToGetIntFor == ReachHoldLocation + return iReach + + ElseIf LocationToGetIntFor == HjaalmarchHoldLocation + return iHjaalmarch + + ElseIf LocationToGetIntFor == WhiterunHoldLocation + return iWhiterun + + ElseIf LocationToGetIntFor == FalkreathHoldLocation + return iFalkreath + + ElseIf LocationToGetIntFor == PaleHoldLocation + return iPale + + ElseIf LocationToGetIntFor == WinterholdHoldLocation + return iWinterhold + + ElseIf LocationToGetIntFor == EastmarchHoldLocation + return iEastmarch + + ElseIf LocationToGetIntFor == RiftHoldLocation + return iRift + + Else + log("CWScript", " WARNING! getIntForHoldLocation() returning -1 because it recieved an unexpected location that isn't a hold: " + LocationToGetIntFor) + return -1 + EndIf + +EndFunction + + +ObjectReference Function getCampaignStartMarker(int Hold) +{Returns an objectReference (xmarker) corresponding to the integer Hold parameter} + + if Hold == iHaafingar ;1 + return CWCampaignStartMarkerHaafingar + + elseif Hold == iReach ;2 + return CWCampaignStartMarkerReach + + elseif Hold == iHjaalmarch ;3 + return CWCampaignStartMarkerHjaalmarch + + elseif Hold == iWhiterun ;4 + return CWCampaignStartMarkerWhiterun + + elseif Hold == iFalkreath ;5 + return CWCampaignStartMarkerFalkreath + + elseif Hold == iPale ;6 + return CWCampaignStartMarkerPale + + elseif Hold == iWinterhold ;7 + return CWCampaignStartMarkerWinterhold + + elseif Hold == iEastmarch ;8 + return CWCampaignStartMarkerEastmarch + + elseif Hold == iRift ;9 + return CWCampaignStartMarkerRift + + EndIf + +EndFunction + + +function initializeFortOwnerKeywordData() + ;The main quest needs to find CWCampaignStartMarkers based on who owns the hold. The CWCampaignMarker objects live in all the forts, therefore I need to set the keyword data for these at game start so without question the Main Quest knows who owns what via keyword data + + FortHraggstadLocation.SetKeywordData(CWOwner, iImperials) + FortSungardLocation.SetKeywordData(CWOwner, iImperials) + FortSnowhawkLocation.SetKeywordData(CWOwner, iImperials) + FortGreymoorLocation.SetKeywordData(CWOwner, iImperials) + FortNeugradLocation.SetKeywordData(CWOwner, iImperials) + + FortDunstadLocation.SetKeywordData(CWOwner, iSons) + FortKastavLocation.SetKeywordData(CWOwner, iSons) + FortAmolLocation.SetKeywordData(CWOwner, iSons) + FortGreenwallLocation.SetKeywordData(CWOwner, iSons) + +EndFunction + +int function getOwner(Location LocationToCheck) +{Returns an int representing the faction that controls the location. Checked the CWOwner keyword data on the location. 1 = Imperials, 2 = Sons} + + int owner = LocationToCheck.GetKeywordData(CWOwner) as Int + + Log("CWScript", "GetOwner(" + LocationToCheck + ") returning " + owner + "(" + FactionName(owner) + ")") + + return owner + +EndFunction + +int Function GetAttacker(Location LocationToCheck) +{Returns and int representing the faction that does not control the location} + + int returnVal + + if GetOwner(LocationToCheck) == iImperials + returnVal = iSons + + Elseif GetOwner(LocationToCheck) == iSons + returnVal = iImperials + + Else + + Log("CWScript", " WARNING: GetAttacker(" + LocationToCheck + ") found unexpected Owner. Expected 1 or 2, instead got " + returnVal, 2, true, true) + + EndIf + + Log("CWScript", "GetAttacker(" + LocationToCheck + ") returning: " + returnVal) + + return returnVal + +EndFunction + +int Function GetDefender(Location LocationToCheck) +{Returns and int representing the faction that does not control the location} + + int returnVal = GetOwner(LocationToCheck) + + Log("CWScript", "GetDefender(" + LocationToCheck + ") returning: " + returnVal) + + return returnVal + +EndFunction + + +bool function PlayersFactionIsAttacker(Location LocationToCheck) + bool returnVal + + returnVal = GetAttacker(LocationToCheck) == PlayerAllegiance + + Log("CWScript", "PlayersFactionIsAttacker(" + LocationToCheck + ") returning: " + returnVal) + + return returnVal + +EndFunction + +bool function PlayersFactionIsDefender(Location LocationToCheck) + bool returnVal + + returnVal = GetDefender(LocationToCheck) == PlayerAllegiance + + Log("CWScript", "PlayersFactionIsDefender(" + LocationToCheck + ") returning: " + returnVal) + + return returnVal + +EndFunction + +bool function ImperialsAreAttacking(Location LocationToCheck) + Log("CWScript", "ImperialsAreAttacking()") + bool returnVal + + returnVal = GetAttacker(LocationToCheck) == iImperials + + Log("CWScript", "ImperialsAreAttacking() returning: " + returnVal) + + return returnVal + +EndFunction + +bool function SonsAreAttacking(Location LocationToCheck) + Log("CWScript", "SonsAreAttacking()") + bool returnVal + + returnVal = GetAttacker(LocationToCheck) == iSons + + Log("CWScript", "SonsAreAttacking() returning: " + returnVal) + + return returnVal + +EndFunction + +bool function IsActorAttacker(actor actorToCheck, Location locationOfBattle) +{Returns true if the actor is in the CWImperial/SonsFaction and that faction is currently the Attacker} + + bool returnVal = GetAttacker(locationOfBattle) == GetActorAllgeiance(actorToCheck) + + Log("CWScript", "IsActorAttacker(" + actorToCheck + ", " + locationOfBattle + ") returning: " + returnVal) + + return returnVal + +EndFunction + +bool function IsActorDefender(actor actorToCheck, Location locationOfBattle) +{Returns true if the actor is in the CWImperial/SonsFaction and that faction is currently the Defender} + return GetDefender(locationOfBattle) == GetActorAllgeiance(actorToCheck) + +EndFunction + + +int function GetWinner(Location LocationOfFinaleBattle, bool AttackerWon = false, bool DefenderWon = False) + Log("CWScript", "GetWinner() LocationOfFinalBattle: " + LocationOfFinaleBattle + " AttackerWon: " + AttackerWon + ", DefenderWon:" + DefenderWon ) + + int returnVar + + if AttackerWon + returnVar = GetAttacker(LocationOfFinaleBattle) + + elseif DefenderWon + returnVar = GetDefender(LocationOfFinaleBattle) + + Else + Log("CWScript", " WARNING: GetWinner() called with NEITHER AtackerWon nor DefenderWon parameters being true!", 2, true, true ) + returnVar = -1 + EndIf + + Log("CWScript", "GetWinner() returning " + returnVar) + + return returnVar + +EndFunction + + +;CALLED BY CWMissionScript +;Note: this should only be called for registering settlments and towns, not capitals +;it's used by main quest negotiations, flavored as "a massacre" with some question as to what happened. Everyone knows what happened at capital battles. +Function RegisterLocationAttacked(Location HoldLocation, location AttackedLocation, int iFaction = 0) +{Called by any mission where a settlement is attacked violently in such a way that people *could* condemn the action. Default iFaction doing the attacking is the CW.Attacker} + if iFaction == 0 + iFaction = GetAttacker(HoldLocation) + EndIf + + if iFaction == iImperials + Log("CWScript", "RegisterLocationAttacked() setting LastLocAttackedByImperials to " + AttackedLocation) + LastLocAttackedByImperials = AttackedLocation + + elseif iFaction == iSons + Log("CWScript", "RegisterLocationAttacked() setting LastLocAttackedBySons to " + AttackedLocation) + LastLocAttackedBySons = AttackedLocation + Else + Log("CWScript", " WARNING: RegisterLocationAttack expected GetAttacker(HoldLocation) to be 1 or 2.", 2, true, true) + EndIf + + LastLocAttacked = AttackedLocation + + Log("CWMissionScript", self + "RegisterLocationAttacked() setting LastLocAttacked to " + AttackedLocation) + +EndFunction + +function RemoveGarrisonFromWar(Location LocationToTurnOff) + Log("CWMissionScript", self + "RemoveGarrisonFromWar(" + LocationToTurnOff + "), REMEMBER TO DISABLE THE ENABLE MARKERS YOURSELF") + + ;-2 because GetKeyWordData() returns -1 if the keyword isn't present + + If LocationToTurnOff.HasKeyword(CWGarrison) + Log("CWMissionScript", self + "RemoveGarrisonFromWar() setting CWGarrison to -2 for location: " + LocationToTurnOff + " REMEMBER TO DISABLE THE ENABLE MARKERS YOURSELF") + LocationToTurnOff.SetKeywordData(CWGarrison, -2) ;NOTE!!! This ONLY works for things with the CWGarrison keyword, which are settlements and towns, etc. that aren't CWGarrisonDefenderOnly, or Camps, or Forts. + + elseif LocationToTurnOff.HasKeyword(CWFort) + Log("CWMissionScript", self + "RemoveGarrisonFromWar() setting CWFort to -2 for location: " + LocationToTurnOff + " REMEMBER TO DISABLE THE ENABLE MARKERS YOURSELF") + LocationToTurnOff.SetKeywordData(CWFort, -2) ;NOTE!!! This ONLY works for things with the CWFort keyword + + Else + Log("CWMissionScript", self + " WARNING: RemoveGarrisonFromWar() found NEITHER CWGarrison NOR CWFort keyword for location : " + LocationToTurnOff + " THIS WILL CAUSE UNEXPECTED BEHAVIOR", 2, true, true) + + EndIf + + +EndFunction + +function AddGarrisonBackToWar(Location LocationToTurnOn, int FactionToOwn = 0, bool SkipSetOwnerCall = False) + Log("CWMissionScript", self + "AddGarrisonBackToWar(" + LocationToTurnOn + ") and will call setOwner() so it will get turned on.") + + If LocationToTurnOn.HasKeyword(CWGarrison) + Log("CWMissionScript", self + "AddGarrisonBackToWar() setting CWGarrison to 0 for location: " + LocationToTurnOn + " and will call setOwner() so it will get turned on.") + LocationToTurnOn.SetKeywordData(CWGarrison, 0) + + elseif LocationToTurnOn.HasKeyword(CWFort) + Log("CWMissionScript", self + "AddGarrisonBackToWar() setting CWFort to 0 for location: " + LocationToTurnOn + " and will call setOwner() so it will get turned on") + LocationToTurnOn.SetKeywordData(CWFort, 0) + + Else + Log("CWMissionScript", self + " WARNING: AddGarrisonBackToWar() found NEITHER CWGarrison NOR CWFort keyword for location : " + LocationToTurnOn + " THIS WILL CAUSE UNEXPECTED BEHAVIOR", 2, true, true) + + EndIf + + if FactionToOwn == 0 ;if it's not explicitly passed in, use the current owner + + FactionToOwn = LocationToTurnOn.GetKeywordData(CWOwner) as Int + + Log("CWMissionScript", self + "AddGarrisonBackToWar() setting FactionToOwn to current owner:" + FactionToOwn) + + endif + + if SkipSetOwnerCall == False + setOwner(LocationToTurnOn, FactionToOwn) + EndIf + +EndFunction + +function AddEnemyFortsToBackToWar(bool ShowDebugMessage = False) + Log("CWMissionScript", self + "AddEnemyFortsToBackToWar()") + + if ShowDebugMessage == True + debug.MessageBox("Setting Enemy Forts to be cleared of bandits and ready for missions. WAIT before testing civil war missions.") + + EndIf + + if EnemyFortsAddedBackToWar == True + Log("CWMissionScript", self + "AddEnemyFortsToBackToWar() EnemyFortsAddedBackToWar == true, so skipping bailing out from adding forts back to war ") + return + EndIf + + if PlayerAllegiance == iImperials + Log("CWMissionScript", self + "AddEnemyFortsToBackToWar() player is Imperial, adding Stormcloak forts (not Fort Greymoor regardless) back to the war by calling AddGarrisonBackToWar.") + + ;AddGarrisonBackToWar(FortGreymoorLocation) - leaving this alone since I'm assuming the majority of players will own the hold, we want them to fight bandits here + + AddGarrisonBackToWar(FortKastavLocation) + AddGarrisonBackToWar(FortDunstadLocation) + AddGarrisonBackToWar(FortAmolLocation) + AddGarrisonBackToWar(FortGreenWallLocation) + + EnemyFortsAddedBackToWar = True + + elseif PlayerAllegiance == iSons + Log("CWMissionScript", self + "AddEnemyFortsToBackToWar() player is Sons, adding Imperial forts (not Fort Greymoor regardless) back to the war by calling AddGarrisonBackToWar().") + + ;AddGarrisonBackToWar(FortGreymoorLocation) - leaving this alone since I'm assuming the majority of players will own the hold, we want them to fight bandits here + + AddGarrisonBackToWar(FortNeugradLocation) + AddGarrisonBackToWar(FortHraggstadLocation) + AddGarrisonBackToWar(FortSungardLocation) + AddGarrisonBackToWar(FortSnowhawkLocation) + + + EnemyFortsAddedBackToWar = True + + Else + Log("CWMissionScript", self + " WARNING: AddEnemyFortsToBackToWar() expected PlayerAllegiance to be 1 or 2, instead got" + PlayerAllegiance, 2, true, true) + + EndIf + + if ShowDebugMessage == True + debug.MessageBox("Done Setting Enemy Forts to be cleared of bandits and ready for missions. You may now test civil war missions.") + + EndIf + + Log("CWMissionScript", self + "AddEnemyFortsToBackToWar() FINSIHED") + +EndFunction + +function SetOwnerKeywordDataOnly(Location LocationToSet, int FactionToOwn) +{used by SetOwner() function... probably not a good idea to call on it's own, unless you know you will soon be following up with a setowner call} + if LocationToSet + LocationToSet.SetKeywordData(CWOwner, FactionToOwn) + EndIf + +EndFunction + +Function setOwner(Location LocationToSet1, int FactionToOwn, Location LocationToSet2 = None, Location LocationToSet3 = None, Location LocationToSet4 = None, \ + Location LocationToSet5 = None, Location LocationToSet6 = None , Location LocationToSet7 = None , Location LocationToSet8 = None, \ + bool SetKeywordDataImmediately = False) +{Sets the CWOwner keyword on LocationToSet based on the FactionToOwn (takes 1,2, or 3, it sets the keyword data to -1, -2, -3 for Imperials, Sons, both factions (ie patrols) respectively). Note: If Faction to Own == -999 it means don't change the keyword, just reset the location - used to reset the guards without changing ownership} + + int SecondsSpentWaiting ;how many seconds spent waiting for callback from CWResetGarrisonQuest + int MaxSecondsToWaitBeforeBailingOut = 600 ;wait 10 minutes for call back from CWResetGarrisonQuest, then give up + + if debugSkipSetOwnerCalls + log("CWScript", "setOnwer() debugSkipSetOwnerCalls is turned on, so we are skipping calls to set owner. This will break things, but is convenient to start campaign faster for certain types of playtesting.", 1) + return + EndIf + + if setKeywordDataImmediately + SetOwnerKeywordDataOnly(LocationToSet1, FactionToOwn) + SetOwnerKeywordDataOnly(LocationToSet2, FactionToOwn) + SetOwnerKeywordDataOnly(LocationToSet3, FactionToOwn) + SetOwnerKeywordDataOnly(LocationToSet4, FactionToOwn) + SetOwnerKeywordDataOnly(LocationToSet5, FactionToOwn) + SetOwnerKeywordDataOnly(LocationToSet6, FactionToOwn) + SetOwnerKeywordDataOnly(LocationToSet7, FactionToOwn) + SetOwnerKeywordDataOnly(LocationToSet8, FactionToOwn) + EndIf + + ;trap any threads that have come in while we are already dealing with previous request(s) + while WaitingForCWResetGarrisonQuest1 || WaitingForCWResetGarrisonQuest2 || WaitingForCWResetGarrisonQuest3 || WaitingForCWResetGarrisonQuest4 + log("CWScript", "setOwner() Wants to process new locations, but we are already processing another request and are still waiting for CWResetGarrison quests to call back.") + Utility.wait(5) + EndWhile + + log("CWScript", "setOwner(), setting WaitingForCWResetGarrisonQuest1/2/3/4/5/6/7/8 to True") + WaitingForCWResetGarrisonQuest1 = true + WaitingForCWResetGarrisonQuest2 = true + WaitingForCWResetGarrisonQuest3 = true + WaitingForCWResetGarrisonQuest4 = true + WaitingForCWResetGarrisonQuest5 = true + WaitingForCWResetGarrisonQuest6 = true + WaitingForCWResetGarrisonQuest7 = true + WaitingForCWResetGarrisonQuest8 = true + + ;The IMPORTANT thing about this function, is that it does NOT return until after all the ResetGarrison quests are all finished running + + ;Start ResetGarrisonX quests (returns false if not starting quest because LocationToSetX is empty) + + ;the reason wrap this in a test if an if statement, is because it is possible that the quest sets the WaitingForCWResetGarrisonX property to false in it's shut down phase before this function returns and we don't want to overwrite that with true returned by this function) + if !setOwnerStartResetQuest(LocationToSet1, FactionToOwn, CWResetGarrisonStart1) + WaitingForCWResetGarrisonQuest1 = false + EndIf + + if !setOwnerStartResetQuest(LocationToSet2, FactionToOwn, CWResetGarrisonStart2) + WaitingForCWResetGarrisonQuest2 = false + EndIf + + if !setOwnerStartResetQuest(LocationToSet3, FactionToOwn, CWResetGarrisonStart3) + WaitingForCWResetGarrisonQuest3 = false + EndIf + + if !setOwnerStartResetQuest(LocationToSet4, FactionToOwn, CWResetGarrisonStart4) + WaitingForCWResetGarrisonQuest4 = false + EndIf + + if !setOwnerStartResetQuest(LocationToSet5, FactionToOwn, CWResetGarrisonStart5) + WaitingForCWResetGarrisonQuest5 = false + EndIf + + if !setOwnerStartResetQuest(LocationToSet6, FactionToOwn, CWResetGarrisonStart6) + WaitingForCWResetGarrisonQuest6 = false + EndIf + + if !setOwnerStartResetQuest(LocationToSet7, FactionToOwn, CWResetGarrisonStart7) + WaitingForCWResetGarrisonQuest7 = false + EndIf + + if !setOwnerStartResetQuest(LocationToSet8, FactionToOwn, CWResetGarrisonStart8) + WaitingForCWResetGarrisonQuest8 = false + EndIf + + + While WaitingForCWResetGarrisonQuest1 || WaitingForCWResetGarrisonQuest2 || WaitingForCWResetGarrisonQuest3 || WaitingForCWResetGarrisonQuest4 || \ + WaitingForCWResetGarrisonQuest5 || WaitingForCWResetGarrisonQuest6 || WaitingForCWResetGarrisonQuest7 || WaitingForCWResetGarrisonQuest8 || \ + CWResetGarrison1.IsStopped() == False || CWResetGarrison2.IsStopped() == False || CWResetGarrison3.IsStopped() == False || CWResetGarrison4.IsStopped() == False || \ + CWResetGarrison5.IsStopped() == False || CWResetGarrison6.IsStopped() == False || CWResetGarrison7.IsStopped() == False || CWResetGarrison8.IsStopped() == False + + if SecondsSpentWaiting >= MaxSecondsToWaitBeforeBailingOut + log("CWScript", "setOwner(): ERROR!!! Have been waiting for call backs from CWResetGarrison1/2/3/4/5/6/7/8 quests for " + SecondsSpentWaiting + " seconds. Giving up." , 2) + return + + Else + log("CWScript", "setOwner() waiting for CWResetGarrison1/2/3/4/5/6/7/8 quests to call back. Have been waiting for " + SecondsSpentWaiting + " seconds.") + +; ; debug.trace(WaitingForCWResetGarrisonQuest1 + " " + \ +; WaitingForCWResetGarrisonQuest2 + " " + \ +; WaitingForCWResetGarrisonQuest3 + " " + \ +; WaitingForCWResetGarrisonQuest4 + " " + \ +; WaitingForCWResetGarrisonQuest5 + " " + \ +; WaitingForCWResetGarrisonQuest6 + " " + \ +; WaitingForCWResetGarrisonQuest7 + " " + \ +; WaitingForCWResetGarrisonQuest8 + " " + \ +; CWResetGarrison1.IsStopped() + " " + \ +; CWResetGarrison2.IsStopped() + " " + \ +; CWResetGarrison3.IsStopped() + " " + \ +; CWResetGarrison4.IsStopped() + " " + \ +; CWResetGarrison5.IsStopped() + " " + \ +; CWResetGarrison6.IsStopped() + " " + \ +; CWResetGarrison7.IsStopped() + " " + \ +; CWResetGarrison8.IsStopped() + " " ) + + SecondsSpentWaiting += 5 + Utility.Wait(5) + + EndIf + EndWhile + + log("CWScript", "setOwner() is finsihed") + +EndFunction + +bool function setOwnerStartResetQuest(Location LocationToSet, int FactionToOwn, Keyword KeywordForResetGarrisonQuest) +{Sub function of setOwner()} + + log("CWScript", "setOwnerStartResetQuest() called with: LocationToSet: " + LocationToSet + ", FactionToOwn: " + FactionToOwn + ", KeywordForResetGarrisonQuest: " + KeywordForResetGarrisonQuest) + + if locationToSet + if FactionToOwn != iCurrentOwner + ;LocationToSet.SetKeyWordData(CWOwner, -(FactionToOwn)) NO LONGER SETTING IT TO NEGAITVE... i was using -1 for obsolete reasons... it's now possible to cause problems because my quest conditions for missions often are CWOwnner != PlayerAllegience (which -1 and -2 will always return true for, so it's possible to get a mission for some place that would be in the middle of switching over) + LocationToSet.SetKeyWordData(CWOwner, FactionToOwn) + log("CWScript", "setOwnerStartResetQuest() setting owner to " + FactionToOwn +"(" + FactionName(FactionToOwn) + ") for " + LocationToSet) + Else + log("CWScript", "setOwnerStartResetQuest() not changing owner, just resetting the garrison for whoever currently owns it.") + EndIf + +; While Game.GetPlayer().IsInLocation(LocationToSet) ;do nothing until the player isn't in same location as the LocToReset +; ;DO NOTHING +; log("CWScript", "setOwnerStartResetQuest() waiting until player is no longer in location:" + LocationToSet) +; utility.wait(1) ;wait a second before checking if if player is in location again +; EndWhile +;THE ABOVE WAY IS NOT AS GOOD BECAUSE IT COULD CAUSE THINGS TO POP IF YOU TECHNICALLY ARE NOT IN THE LOCATION BUT YOU CAN STILL "SEE INTO" IT -- commenting it out rather than deleting for now + + While LocationToSet.IsLoaded() ;do nothing until the player isn't in same area as the LocToReset + ;DO NOTHING + log("CWScript", "setOwnerStartResetQuest() waiting until location is no longer loaded (ie out of the 5x5):" + LocationToSet) + utility.wait(1) ;wait a second before checking if if player is in location again + EndWhile + + log("CWScript", "setOwnerStartResetQuest() starting reset garrison quest, CWResetGarrissonX.SendStoryEvent(" + LocationToSet + ")") + KeywordForResetGarrisonQuest.SendStoryEvent(LocationToSet) + + Else + return False ;we aren't starting a quest + EndIf + + log("CWScript", "setOwnerStartResetQuest() finished.") + + return True ;we are starting a quest -- NOTE don't do anything with this return value because it's POSSIBLE that the quest's shut down phase happens (setting the property in quest to false) before this returns true. We don't want to overwrite it: see note SetOwner() where this function is called) + + + +EndFunction + + + +function WinHoldOffScreenIfNotDoingCapitalBattles(Location HoldToWin, bool AttackersHaveWon = true, bool DefendersHaveWon = False) +;CALLED BY STAGE 9000 IN THE CWFortSiegeCaptial/Fort Quests for regular Fort Battles +;AND STAGE 200 in CWMission04 Quest - Rescue Prisoners from fort and take over +;REPLICATE WHAT USED TO HAPPEN AFTER BATTLES FOR CAPITAL CITIES AND MINOR HOLDS + + log("CWScript", "WinHoldOffScreen(HoldToWin:" + HoldToWin + ", AttackersHaveWon:" + AttackersHaveWon + ", DefendersHaveWon:" + DefendersHaveWon + ")") + + ;IF WE LATER DECIDE TO REIMPLEMENT THE ATTACKS ON THE CAPITALS + ;THE LOGIC FOR WHICH WE WILL DO CAN GO HERE + + WinHoldAndSetOwnerKeywordDataOnly(HoldToWin, AttackersHaveWon, DefendersHaveWon) + + CompleteCWObj(HoldToWin) + + ;if the peace treaty quest is running, shut it down, as it's now too late to have a peace treaty + if HoldToWin == HjaalmarchHoldLocation || HoldToWin == WinterholdHoldLocation + + bool MQ302Running = MQ302.isRunning() + int MQ302Stage = MQ302.getstage() + + log("CWScript", "WinHoldOffScreen(HoldToWin:" + HoldToWin + ") MQ302 is running? [" + MQ302Running + "], MQ302 stage: " + MQ302Stage) + + if MQ302Running && MQ302Stage < 40 + log("CWScript", "WinHoldOffScreen(HoldToWin:" + HoldToWin + ") MQ302 is running and < stage 40, so calling it's stage 350 to shut it down.") + MQ302.setStage(350) + EndIf + + EndIf + + ;GIVE OWNERSHIP - WAITS to return until player isn't in various locations in the hold + WinHoldAndSetOwner(HoldToWin, AttackersHaveWon, DefendersHaveWon) + +EndFunction + + +function WinHoldAndSetOwnerKeywordDataOnly(Location HoldLocationToSet, bool AttackersWon, bool DefendersWon) +{Call the moment one side has won a siege so faction leader has appropriate dialogue } + + WinningHoldAndSettingOwnerPleaseWait = True + + log("CWScript", "WinHoldAndSetOwnerKeywordDataOnly() HoldLocationToSet:" + HoldLocationToSet + ", AttackersWon: " + AttackersWon + ", DefendersWon: " + DefendersWon) + + int winner = GetWinner(HoldLocationToSet, AttackersWon, DefendersWon) + + SetOwnerKeywordDataOnly(HoldLocationToSet, winner) + WinHoldAndSetOwnerAlreadySetKeyword = True + + log("CWScript", "WinHoldAndSetOwnerKeywordDataOnly() Will call ClearHoldCrimeGold(" + HoldLocationToSet + ")") + ClearHoldCrimeGold(HoldLocationToSet) + + WinningHoldAndSettingOwnerPleaseWait = False + +EndFunction + +function WinHoldAndSetOwner(Location HoldLocationToSet, bool AttackersWon, bool DefendersWon) +{Call at the end of a siege in shutdown stage} + + int waitingFor + + while WinningHoldAndSettingOwnerPleaseWait + utility.wait(1) + WaitingFor += 1 + log("CWScript", "WinHoldAndSetOwner(): WinningHoldAndSettingOwnerPleaseWait == true, meaning WinHoldAndSetOwnerKeywordOnly is currently processing... waiting for:" + waitingFor) + EndWhile + + log("CWScript", "WinHoldAndSetOwner() HoldLocationToSet:" + HoldLocationToSet + ", AttackersWon: " + AttackersWon + ", DefendersWon: " + DefendersWon) + + int NewOwner + + if WinHoldAndSetOwnerAlreadySetKeyword == False + log("CWScript", "WinHoldAndSetOwner() sees WinHoldAndSetOwnerAlreadySetKeyword == false, so we will determine the new owner with GetWinner()") + NewOwner = GetWinner(HoldLocationToSet, AttackersWon, DefendersWon) + Else + log("CWScript", "WinHoldAndSetOwner() sees WinHoldAndSetOwnerAlreadySetKeyword == true, so we will determine the new owner with GetKeywordData()") + NewOwner = HoldLocationToSet.GetKeywordData(CWOwner) as Int + WinHoldAndSetOwnerAlreadySetKeyword = False + EndIf + + log("CWScript", "WinHoldAndSetOwner() Will call ClearHoldCrimeGold(" + HoldLocationToSet + ")") + ClearHoldCrimeGold(HoldLocationToSet) + + log("CWScript", "WinHoldAndSetOwner() Will call SetHoldOwner() for faction:" + NewOwner) + SetHoldOwner(HoldLocationToSet, NewOwner) + +EndFunction + + +function SetHoldOwner(Location HoldLocationToSet, int factionToOwn) + log("CWScript", "SetHoldOwner(" + HoldLocationToSet + ", " + factionToOwn + ") calling SetOwner()") + + SetOwnerKeywordDataOnly(HoldLocationToSet, factionToOwn) + + SetHoldOwnerByInt(GetHoldID(HoldLocationToSet), factionToOwn) + +EndFunction + +;OLD VERSION - used by MQ +Function SetHoldOwnerByInt(int HoldToSet, int FactionToOwn, bool DiplomaticVictory = false ) +{Takes int HoldToSet and int FactionToOwn, and calls the appropriate setOwnerXXX(FactionToOwn) function - DiplomaticVictory is for if hold was won through MQ302, and sets keyword data which is used for conditions in dialogue with faction leader} + + if HoldToSet == iHaafingar ;1 + AddGarrisonBackToWar(FortHraggstadLocation, FactionToOwn, SkipSetOwnerCall = DiplomaticVictory) + setOwnerHaafingar(FactionToOwn, DiplomaticVictory) + + elseif HoldToSet == iReach ; 2 + AddGarrisonBackToWar(FortSungardLocation, FactionToOwn, SkipSetOwnerCall = DiplomaticVictory) + setOwnerReach(FactionToOwn, DiplomaticVictory) + + elseif HoldToSet == iHjaalmarch ;3 + AddGarrisonBackToWar(FortSnowhawkLocation, FactionToOwn, SkipSetOwnerCall = DiplomaticVictory) + setOwnerHjaalmarch(FactionToOwn, DiplomaticVictory) + + elseif HoldToSet == iWhiterun ;4 + AddGarrisonBackToWar(FortGreymoorLocation, FactionToOwn, SkipSetOwnerCall = DiplomaticVictory) + setOwnerWhiterun(FactionToOwn, DiplomaticVictory) + + elseif HoldToSet == iFalkreath ;5 + AddGarrisonBackToWar(FortNeugradLocation, FactionToOwn, SkipSetOwnerCall = DiplomaticVictory) + setOwnerFalkreath(FactionToOwn, DiplomaticVictory) + + elseif HoldToSet == iPale ;6 + AddGarrisonBackToWar(FortDunstadLocation, FactionToOwn, SkipSetOwnerCall = DiplomaticVictory) + setOwnerPale(FactionToOwn, DiplomaticVictory) + + elseif HoldToSet == iWinterhold ;7 + AddGarrisonBackToWar(FortKastavLocation, FactionToOwn, SkipSetOwnerCall = DiplomaticVictory) + setOwnerWinterhold(FactionToOwn, DiplomaticVictory) + + elseif HoldToSet == iEastmarch ;8 + AddGarrisonBackToWar(FortAmolLocation, FactionToOwn, SkipSetOwnerCall = DiplomaticVictory) + setOwnerEastmarch(FactionToOwn, DiplomaticVictory) + + elseif HoldToSet == iRift ;9 + AddGarrisonBackToWar(FortGreenwallLocation, FactionToOwn, SkipSetOwnerCall = DiplomaticVictory) + setOwnerRift(FactionToOwn, DiplomaticVictory) + + else + log("CWScript", "SetHoldOwnerByInt(" + HoldToSet + ") parametered unrecognized. Expected an int 1-9 as HoldToCheck, got something else.") + EndIf + +EndFunction + + + +Function setCountHoldProperties() +{Calls setCountHoldsImperial() and setCountHoldsSons()} + + setCountHoldsImperial() + setCountHoldsSons() + +EndFunction + +Function setCountHoldsImperial() +{Sets CountHoldsImperial property and associated CWCountHoldsImperial global... note, call this AFTER setting any new ownerXXX property values, such as in the setOwnerXXX() function.} + int count = 0 + + if OwnerHaafingar == iImperials + count += 1 + EndIf + if OwnerReach == iImperials + count += 1 + EndIf + if OwnerHjaalmarch == iImperials + count += 1 + EndIf + if OwnerWhiterun == iImperials + count += 1 + EndIf + if OwnerFalkreath == iImperials + count += 1 + EndIf + if OwnerPale == iImperials + count += 1 + EndIf + if OwnerWinterhold == iImperials + count += 1 + EndIf + if OwnerEastmarch == iImperials + count += 1 + EndIf + if OwnerRift == iImperials + count += 1 + EndIf + + countHoldsImperial = count + CWCountHoldsImperial.value = count + +EndFunction + +Function setCountHoldsSons() +{Sets CountHoldsSons property and associated CWCountHoldsSon global... note, call this AFTER setting any new ownerXXX property values, such as in the setOwnerXXX() function.} + int count = 0 + + if OwnerHaafingar == iSons + count += 1 + EndIf + if OwnerReach == iSons + count += 1 + EndIf + if OwnerHjaalmarch == iSons + count += 1 + EndIf + if OwnerWhiterun == iSons + count += 1 + EndIf + if OwnerFalkreath == iSons + count += 1 + EndIf + if OwnerPale == iSons + count += 1 + EndIf + if OwnerWinterhold == iSons + count += 1 + EndIf + if OwnerEastmarch == iSons + count += 1 + EndIf + if OwnerRift == iSons + count += 1 + EndIf + + countHoldsSons = count + CWCountHoldsSons.value = count + +EndFunction + + + +;bool function IsSiegeRunningHere(Location LocationToCheck) +; +; location SiegeLoc = CWSiegeCity.GetLocation() +; +; bool returnVar +; +; if CWSiegeS.IsStopped() == False && SiegeLoc == LocationToCheck +; returnVar = True +; +; Else +; returnVar = False +; +; EndIf +; +; log("CWScript", "IsSiegeRunningHere(" + LocationToCheck + ") returning: " + returnVar) +; +; return returnVar +; +;EndFunction + + +;POSSIBLY OBSOLETE +Function ResetHolds() +;called by CWHoldManagerScript attached to CW + + log("CWScript", "ResetHolds()") + + setOwnerHaafingar(iCurrentOwner) + setOwnerReach(iCurrentOwner) + setOwnerHjaalmarch(iCurrentOwner) + setOwnerWhiterun(iCurrentOwner) + setOwnerFalkreath(iCurrentOwner) + setOwnerPale(iCurrentOwner) + setOwnerWinterhold(iCurrentOwner) + setOwnerEastmarch(iCurrentOwner) + setOwnerRift(iCurrentOwner) + +EndFunction + +Function setInitalOwnerKeywordDataOnly() +{A quick way to initialize keyword data at game start only, so Civil War missions fill aliases correctly. The more "thorough" function is SetInitialOwners()} + + ;# Haafingar + HaafingarHoldLocation.SetKeywordData(CWOwner, iImperials) + + FortHraggstadLocation.SetKeywordData(CWOwner, iImperials) + SolitudeLocation.SetKeywordData(CWOwner, iImperials) + + SolitudeSawmillLocation.SetKeywordData(CWOwner, iImperials) + KatlasFarmLocation.SetKeywordData(CWOwner, iImperials) + DragonBridgeLocation.SetKeywordData(CWOwner, iImperials) + + ;# Reach + ReachHoldLocation.SetKeywordData(CWOwner, iImperials) + + FortSungardLocation.SetKeywordData(CWOwner, iImperials) + MarkarthLocation.SetKeywordData(CWOwner, iImperials) + + CidhnaMineLocation.SetKeywordData(CWOwner, iImperials) + LeftHandMineLocation.SetKeywordData(CWOwner, iImperials) + SalviusFarmLocation.SetKeywordData(CWOwner, iImperials) + KarthwastenLocation.SetKeywordData(CWOwner, iImperials) + OldHroldanLocation.SetKeywordData(CWOwner, iImperials) + KolskeggrMineLocation.SetKeywordData(CWOwner, iImperials) + + ;# Hjaalmarch + HjaalmarchHoldLocation.SetKeywordData(CWOwner, iImperials) + + FortSnowhawkLocation.SetKeywordData(CWOwner, iImperials) + MorthalLocation.SetKeywordData(CWOwner, iImperials) + + StonehillsLocation.SetKeywordData(CWOwner, iImperials) +; FrostRiverFarmLocation.SetKeywordData(CWOwner, iImperials) + + ;# Whiterun + WhiterunHoldLocation.SetKeywordData(CWOwner, iImperials) + + FortGreymoorLocation.SetKeywordData(CWOwner, iImperials) + WhiterunLocation.SetKeywordData(CWOwner, iImperials) + + BattleBornFarmLocation.SetKeywordData(CWOwner, iImperials) + ChillfurrowFarmLocation.SetKeywordData(CWOwner, iImperials) + PelagiaFarmLocation.SetKeywordData(CWOwner, iImperials) + RoriksteadLocation.SetKeywordData(CWOwner, iImperials) + RiverwoodLocation.SetKeywordData(CWOwner, iImperials) +; BarleydarkFarmLocation.SetKeywordData(CWOwner, iImperials) + + ;# Falkreath + FalkreathHoldLocation.SetKeywordData(CWOwner, iImperials) + + FortNeugradLocation.SetKeywordData(CWOwner, iImperials) + FalkreathLocation.SetKeywordData(CWOwner, iImperials) + +; GraniteHillLocation.SetKeywordData(CWOwner, iImperials) + HelgenLocation.SetKeywordData(CWOwner, iImperials) +; BearsCaveMillLocation.SetKeywordData(CWOwner, iImperials) + HalfmoonMillLocation.SetKeywordData(CWOwner, iImperials) + + ;# Pale + PaleHoldLocation.SetKeywordData(CWOwner, iSons) + + FortDunstadLocation.SetKeywordData(CWOwner, iSons) + DawnstarLocation.SetKeywordData(CWOwner, iSons) + +; HeljarchenLocation.SetKeywordData(CWOwner, iSons) + AngasMillLocation.SetKeywordData(CWOwner, iSons) + LoreiusFarmLocation.SetKeywordData(CWOwner, iSons) + + ;# Winterhold + WinterholdHoldLocation.SetKeywordData(CWOwner, iSons) + + FortKastavLocation.SetKeywordData(CWOwner, iSons) + WinterholdLocation.SetKeywordData(CWOwner, iSons) + + WhistlingMineLocation.SetKeywordData(CWOwner, iSons) + + ;# Eastmarch + EastmarchHoldLocation.SetKeywordData(CWOwner, iSons) + + FortAmolLocation.SetKeywordData(CWOwner, iSons) + WindhelmLocation.SetKeywordData(CWOwner, iSons) + + BrandyMugFarmLocation.SetKeywordData(CWOwner, iSons) + HlaaluFarmLocation.SetKeywordData(CWOwner, iSons) + HollyfrostFarmLocation.SetKeywordData(CWOwner, iSons) + KynesgroveLocation.SetKeywordData(CWOwner, iSons) + DarkwaterCrossingLocation.SetKeywordData(CWOwner, iSons) + MixwaterMillLocation.SetKeywordData(CWOwner, iSons) + + ;# Rift + RiftHoldLocation.SetKeywordData(CWOwner, iSons) + + FortGreenwallLocation.SetKeywordData(CWOwner, iSons) + RiftenLocation.SetKeywordData(CWOwner, iSons) + + SnowShodFarmLocation.SetKeywordData(CWOwner, iSons) + ;GoldenglowFarmLocation -- GoldenGlowFarm is NOT a normal location. It's quest specific area spawning it's own guards, and should not be part of the Civil War. + MerryfairFarmLocation.SetKeywordData(CWOwner, iSons) + IvarsteadLocation.SetKeywordData(CWOwner, iSons) + ShorsStoneLocation.SetKeywordData(CWOwner, iSons) + HeartwoodMillLocation.SetKeywordData(CWOwner, iSons) + SarethiFarmLocation.SetKeywordData(CWOwner, iSons) + +EndFunction + + +Function setInitialOwners() +{Called in the OnInit block, one time set up of initial owners of all the locations.} + + setOwnerHaafingar(iImperials) + setOwnerReach(iImperials) + setOwnerHjaalmarch(iImperials) + setOwnerWhiterun(iImperials) + setOwnerFalkreath(iImperials) + setOwnerPale(iSons) + setOwnerWinterhold(iSons) + setOwnerEastmarch(iSons) + setOwnerRift(iSons) + +EndFunction + + +Function setOwnerHaafingar(int FactionToOwn, bool DiplomaticVictory = false) + log("CWScript", "CW Script setOwnerHaafingar() started." + "FactionToOwn: " + FactionToOwn + ", DiplomaticVictory: " + DiplomaticVictory) + + if DiplomaticVictory + HaafingarHoldLocation.SetKeywordData(CWDiplomaticVictory, 1) + ClearHoldCrimeGold(HaafingarHoldLocation) + EndIf + + if FactionToOwn != iCurrentOwner + ownerHaafingar = FactionToOwn + HaafingarHoldLocation.SetKeywordData(CWOwner, FactionToOwn) + EndIf + + setCountHoldProperties() + setOwner(FortHraggstadLocation, FactionToOwn, MilitaryCampHaafingarSonsLocation, SolitudeLocation, SolitudeSawmillLocation, KatlasFarmLocation, DragonBridgeLocation) + + + log("CWScript", "CW Script setOwnerHaafingar() finished.") + +EndFunction + +Function setOwnerReach(int FactionToOwn, bool DiplomaticVictory = false) + log("CWScript", "CW Script setOwnerReach() started." + "FactionToOwn: " + FactionToOwn + ", DiplomaticVictory: " + DiplomaticVictory) + + if DiplomaticVictory + ReachHoldLocation.SetKeywordData(CWDiplomaticVictory, 1) + ClearHoldCrimeGold(ReachHoldLocation) + EndIf + + if FactionToOwn != iCurrentOwner + ownerReach = FactionToOwn + ReachHoldLocation.SetKeywordData(CWOwner, FactionToOwn) + EndIf + + setCountHoldProperties() + + setOwner(FortSungardLocation, FactionToOwn, MilitaryCampReachImperialLocation, MilitaryCampReachSonsLocation) + setOwner(MarkarthLocation, FactionToOwn, CidhnaMineLocation, LeftHandMineLocation, SalviusFarmLocation, KarthwastenLocation, OldHroldanLocation, KolskeggrMineLocation) + + log("CWScript", "CW Script setOwnerReach() finished.") + +EndFunction + +Function setOwnerHjaalmarch(int FactionToOwn, bool DiplomaticVictory = false) + log("CWScript", "CW Script setOwnerHjaalmarch() started." + "FactionToOwn: " + FactionToOwn + ", DiplomaticVictory: " + DiplomaticVictory) + + if DiplomaticVictory + HjaalmarchHoldLocation.SetKeywordData(CWDiplomaticVictory, 1) + ClearHoldCrimeGold(HjaalmarchHoldLocation) + EndIf + + if FactionToOwn != iCurrentOwner + ownerHjaalmarch = FactionToOwn + HjaalmarchHoldLocation.SetKeywordData(CWOwner, FactionToOwn) + EndIf + + setCountHoldProperties() + + setOwner(FortSnowhawkLocation, FactionToOwn, MilitaryCampHjaalmarchImperialLocation, MilitaryCampHjaalmarchSonsLocation, MorthalLocation, StonehillsLocation) + + log("CWScript", "CW Script setOwnerHjaalmarch() finished.") + +EndFunction + +Function setOwnerWhiterun(int FactionToOwn, bool DiplomaticVictory = false) + log("CWScript", "CW Script setOwnerWhiterun() started." + "FactionToOwn: " + FactionToOwn + ", DiplomaticVictory: " + DiplomaticVictory) + + if DiplomaticVictory + WhiterunHoldLocation.SetKeywordData(CWDiplomaticVictory, 1) + ClearHoldCrimeGold(WhiterunHoldLocation) + EndIf + + if FactionToOwn != iCurrentOwner + ownerWhiterun = FactionToOwn + WhiterunHoldLocation.SetKeywordData(CWOwner, FactionToOwn) + EndIf + + setCountHoldProperties() + + setOwner(FortGreymoorLocation, FactionToOwn, MilitaryCampWhiterunImperialLocation, MilitaryCampWhiterunSonsLocation) + setOwner(WhiterunLocation, FactionToOwn, BattleBornFarmLocation, ChillfurrowFarmLocation, PelagiaFarmLocation, RoriksteadLocation, RiverwoodLocation) + + log("CWScript", "CW Script setOwnerWhiterun() finished.") + +EndFunction + +Function setOwnerFalkreath(int FactionToOwn, bool DiplomaticVictory = false) + log("CWScript", "CW Script setOwnerFalkreath() started." + "FactionToOwn: " + FactionToOwn + ", DiplomaticVictory: " + DiplomaticVictory) + + if DiplomaticVictory + FalkreathHoldLocation.SetKeywordData(CWDiplomaticVictory, 1) + ClearHoldCrimeGold(FalkreathHoldLocation) + EndIf + + if FactionToOwn != iCurrentOwner + ownerFalkreath = FactionToOwn + FalkreathHoldLocation.SetKeywordData(CWOwner, FactionToOwn) + EndIf + + setCountHoldProperties() + + setOwner(FortNeugradLocation, FactionToOwn, MilitaryCampFalkreathImperialLocation, MilitaryCampFalkreathSonsLocation, FalkreathLocation, HelgenLocation, HalfmoonMillLocation) + + log("CWScript", "CW Script setOwnerFalkreath() finished.") + +EndFunction + +Function setOwnerPale(int FactionToOwn, bool DiplomaticVictory = false) + log("CWScript", "CW Script setOwnerPale() started." + "FactionToOwn: " + FactionToOwn + ", DiplomaticVictory: " + DiplomaticVictory) + + if DiplomaticVictory + PaleHoldLocation.SetKeywordData(CWDiplomaticVictory, 1) + ClearHoldCrimeGold(PaleHoldLocation) + EndIf + + if FactionToOwn != iCurrentOwner + ownerPale = FactionToOwn + PaleHoldLocation.SetKeywordData(CWOwner, FactionToOwn) + EndIf + + setCountHoldProperties() + + setOwner(FortDunstadLocation, FactionToOwn, MilitaryCampPaleImperialLocation, MilitaryCampPaleSonsLocation, DawnstarLocation, AngasMillLocation, LoreiusFarmLocation) + + log("CWScript", "CW Script setOwnerPale() finished.") + +EndFunction + +Function setOwnerWinterhold(int FactionToOwn, bool DiplomaticVictory = false) + log("CWScript", "CW Script setOwnerWinterhold() started." + "FactionToOwn: " + FactionToOwn + ", DiplomaticVictory: " + DiplomaticVictory) + + if DiplomaticVictory + WinterholdHoldLocation.SetKeywordData(CWDiplomaticVictory, 1) + ClearHoldCrimeGold(WinterholdHoldLocation) + EndIf + + if FactionToOwn != iCurrentOwner + ownerWinterhold = FactionToOwn + WinterholdHoldLocation.SetKeywordData(CWOwner, FactionToOwn) + EndIf + + setCountHoldProperties() + + setOwner(FortKastavLocation, FactionToOwn, MilitaryCampWinterholdImperialLocation, MilitaryCampWinterholdSonsLocation, WinterholdLocation, WhistlingMineLocation) + + log("CWScript", "CW Script setOwnerWinterhold() finished.") + +EndFunction + +Function setOwnerEastmarch(int FactionToOwn, bool DiplomaticVictory = false) + log("CWScript", "CW Script setOwnerEastmarch() started." + "FactionToOwn: " + FactionToOwn + ", DiplomaticVictory: " + DiplomaticVictory) + + if DiplomaticVictory + EastmarchHoldLocation.SetKeywordData(CWDiplomaticVictory, 1) + ClearHoldCrimeGold(EastmarchHoldLocation) + EndIf + + if FactionToOwn != iCurrentOwner + ownerEastmarch = FactionToOwn + EastmarchHoldLocation.SetKeywordData(CWOwner, FactionToOwn) + EndIf + + setCountHoldProperties() + + setOwner(FortAmolLocation, FactionToOwn, MilitaryCampEastmarchImperialLocation) + setOwner(WindhelmLocation, FactionToOwn, BrandyMugFarmLocation, HlaaluFarmLocation, HollyfrostFarmLocation, KynesgroveLocation, DarkwaterCrossingLocation, MixwaterMillLocation) + + log("CWScript", "CW Script setOwnerEastmarch() finished.") + + EndFunction + +Function setOwnerRift(int FactionToOwn, bool DiplomaticVictory = false) + log("CWScript", "CW Script setOwnerRift() started." + "FactionToOwn: " + FactionToOwn + ", DiplomaticVictory: " + DiplomaticVictory) + + if DiplomaticVictory + RiftHoldLocation.SetKeywordData(CWDiplomaticVictory, 1) + ClearHoldCrimeGold(RiftHoldLocation) + EndIf + + if FactionToOwn != iCurrentOwner + ownerRift = FactionToOwn + RiftHoldLocation.SetKeywordData(CWOwner, FactionToOwn) + EndIf + + setCountHoldProperties() + + setOwner(FortGreenwallLocation, FactionToOwn, MilitaryCampRiftImperialLocation, MilitaryCampRiftSonsLocation) + setOwner(RiftenLocation, FactionToOwn, SnowShodFarmLocation, MerryfairFarmLocation, IvarsteadLocation, ShorsStoneLocation, HeartwoodMillLocation, SarethiFarmLocation) + + ;Reminder: -- GoldenGlowFarm is NOT a normal location. It's quest specific area spawning it's own guards, and should not be part of the Civil War. + + log("CWScript", "CW Script setOwnerRift() finished.") + +EndFunction + + +Function CreateMissions(Location HoldLocation, ObjectReference CurrentFieldCO, bool ForceFinalSiege = False, ObjectReference CampaignStartMarker = None) + + if WarIsActive == -1 + log("CWScript", "CreateMissions(" + HoldLocation + ", " + CurrentFieldCO + ") WarIsActive != 1, so we are NOT creating story events", 1, 1, true) + + return + + EndIf + + log("CWScript", "CreateMissions(" + HoldLocation + ", " + CurrentFieldCO + ") creating story events.") + + int HoldID = GetHoldID(HoldLocation) + GlobalVariable myCWObjGlobal = GetCWObjGlobal(HoldID) + + +; ;*** THIS IS A HACK FOR NEW PARADIGM TO FIT BACKWARDS COMPATIBLE WITH THE OLDER SYSTEM. RATHER THAN DOING RANDOM MISSIONS UNTIL THE READINESS REACHES 99%, WE ARE SIMPLY COUNTING THE NUMBER OF MISSIONS +; if HoldLocation == FalkreathHoldLocation && CWCountMissionsDone.GetValue() == 1 +; myCWObjGlobal.SetValue(99) +; +; elseif HoldLocation == ReachHoldLocation && CWCountMissionsDone.GetValue() == 3 +; myCWObjGlobal.SetValue(99) +; +; elseif HoldLocation == HjaalmarchHoldLocation && CWCountMissionsDone.GetValue() == 5 +; myCWObjGlobal.SetValue(99) +; +; elseif HoldLocation == HaafingarHoldLocation && CWCountMissionsDone.GetValue() == 6 +; myCWObjGlobal.SetValue(99) +; +; elseif HoldLocation == PaleHoldLocation && CWCountMissionsDone.GetValue() == 2 +; myCWObjGlobal.SetValue(99) +; +; elseif HoldLocation == RiftHoldLocation && CWCountMissionsDone.GetValue() == 4 +; myCWObjGlobal.SetValue(99) +; +; elseif HoldLocation == WinterholdHoldLocation && CWCountMissionsDone.GetValue() == 5 +; myCWObjGlobal.SetValue(99) +; +; elseif HoldLocation == EastmarchHoldLocation && CWCountMissionsDone.GetValue() == 6 +; myCWObjGlobal.SetValue(99) +; +; +; Else +; myCWObjGlobal.SetValue(0) +; +; EndIf +; +; ;*** + + + ;*** THIS IS A HACK FOR NEW PARADIGM TO FIT BACKWARDS COMPATIBLE WITH THE OLDER SYSTEM. + if HoldLocation == HaafingarHoldLocation && HaafingarFortBattleComplete ;set in CWFortSiegeFort stage 9000 + log("CWScript", "CreateMissions() HaafingarHoldLocation and HaafingarFortBattleComplete, setting CWObjHaafingar to 99") + myCWObjGlobal.SetValue(99) + + elseif HoldLocation == EastmarchHoldLocation && EastmarchFortBattleComplete ;set in CWFortSiegeFort stage 9000 + log("CWScript", "CreateMissions() EastmarchHoldLocation and EastmarchFortBattleComplete, setting CWObjEastmarch to 99") + myCWObjGlobal.SetValue(99) + + else + log("CWScript", "CreateMissions() Not a final hold, or not ready for final battle, setting CWObjxxx to 0") + myCWObjGlobal.SetValue(0) + + endif + ;*** + + + if myCWObjGlobal.GetValue() >= 99 || ForceFinalSiege == true + log("CWScript", "CreateMissions() myCWObjGlobal >= 100, will start resolution mission, checking to see if the capital is a city") + + Location Capital = GetCapitalLocationForHold(HoldLocation) + + if Capital.HasKeyword(LocTypeCity) + + ;ITS POSSIBLE YOU CAN TRIGGER "DEFENSE" SIEGES IF THE CWOBJ IS 99 (which for ease of implementation Haagingar and Eastmarch are set to) + ;WE DON'T WANT THAT TO HAPPEN THUS THIS CHECK: + if (Capital == SolitudeLocation && PlayerAllegiance == iImperials) || (Capital == WindhelmLocation && PlayerAllegiance == iSons) + log("CWScript", "CreateMissions() Capital is final hold capital, owned by player's faction, not generating defense siege:" + Capital + ", playerAllegiance =" + PlayerAllegiance, 1) + + Else + log("CWScript", "CreateMissions() Capital is a city, will start CWSiege quest") + CWSiegeStart.SendStoryEvent(Capital, CurrentFieldCO) + + EndIf + + + Else + if HoldLocation.GetKeywordData(CWOwner) == PlayerAllegiance + log("CWScript", " WARNING: CreateMissions() Capital is not a city AND player's faction owns the hold, not implemented fully", 2, true, true) + ;CWFortSiegeMinorCapitalStart.SendStoryEvent(Capital, CurrentFieldCO, CurrentFieldCO) + + Else + log("CWScript", "CreateMissions() Capital is not a city, player's faction does not own the hold, will start a CWFortSiege quest using CWFortSiegeMinorCapitalStart keyword") + + ;safety check, in case you just finished a capital siege, and before it finished shutting down, you get another one - highly unlikely, put I can envision happening + int waitingFor + + + While CWFortSiegeCapital.IsStopped() == False + waitingFor += 1 + utility.wait(1) + + Log("CWScript", self + "CreateMissions(" +HoldLocation + ") WAITING for CWFortSiegeCapital.IsStopped() == false. Have been waiting for:" + waitingFor, 1, true, true) + + ;this is important enough to make sure even if we aren't explicitly testing in Civil War debug mode we get a message about it +; debug.trace(self + "CreateMissions(" + HoldLocation + ") WAITING for CWFortSiegeCapital.IsStopped() == false. Have been waiting for:" + waitingFor, 1) + + + ;!!!NEED A CHECK HERE TO MAKE SURE THAT THE CWFortSiegeCapital ISN'T FILLED ALREADY WITH THIS Capital... + if CWFortSiegeCapitalFort.GetLocation() != Capital + log("CWScript", "CreateMissions(" + HoldLocation + ") sees the Capital " + Capital + " is already in CWFortSiegeCapital Fort Aliases, BAILING OUT of CreateMissions().", 1 ) + return + EndIf + + + EndWhile + + log("CWScript", "CreateMissions() Calling CWFortSiegeMinorCapitalStart.SendStoryEvent(" + Capital + ", " + CurrentFieldCO + ", " + CampaignStartMarker + ")") + CWFortSiegeMinorCapitalStart.SendStoryEvent(Capital, CurrentFieldCO, CampaignStartMarker) + + EndIf + + endif + + Else + log("CWScript", "CreateMissions() myCWObjGlobal < 100, will start normal missions") + + CWMissionStart.SendStoryEvent(HoldLocation, CurrentFieldCO, CampaignStartMarker, aiValue1 = 1) + + EndIf + + + log("CWScript", "CreateMissions(" + HoldLocation + ", " + CurrentFieldCO + "," + CampaignStartMarker + ") done creating story events.") + +EndFunction + +function SetFieldCOAlias(ObjectReference RefToForceIntoFieldCOAlias) + log("CWScript", "SetFieldCOAlias(" + RefToForceIntoFieldCOAlias + ")") + + FieldCO.ForceRefTo(RefToForceIntoFieldCOAlias) +EndFunction + +function GiveMissionReward() + log("CWScript", "GiveMissionReward()") + Game.GetPlayer().AddItem(CWMissionReward) + +EndFunction + + +function setPlayerFactionRank(int RankToSetTo) + log("CWScript", "setPlayerFactionRank([" + RankToSetTo + "]) and adding reward.") + + PlayerRank = RankToSetTo + + Actor PlayerRef = Game.GetPlayer() + + if PlayerAllegiance == iImperials + + if RankToSetTo == 1 + Game.GetPlayer().AddItem(CWRank1RewardImperial) + Elseif RankToSetTo == 2 + Game.GetPlayer().AddItem(CWRank2RewardImperial) + ElseIf RankToSetTo == 3 + Game.GetPlayer().AddItem(CWRank3RewardImperial) + elseif RankToSetTo == 4 + Game.GetPlayer().AddItem(CWRank4RewardImperial) + Else + log("CWScript", "setPlayerFactionRank() expected RankToSetTo to be 1,2,3 or 4. Instead got:" + RankToSetTo, 2, true) + EndIf + + Elseif PlayerAllegiance == iSons + + if RankToSetTo == 1 + Game.GetPlayer().AddItem(CWRank1RewardSons) + UlfricRef.SetRelationshipRank(PlayerRef, 1) + Elseif RankToSetTo == 2 + Game.GetPlayer().AddItem(CWRank2RewardSons) + UlfricRef.SetRelationshipRank(PlayerRef, 2) + ElseIf RankToSetTo == 3 + Game.GetPlayer().AddItem(CWRank3RewardSons) + elseif RankToSetTo == 4 + Game.GetPlayer().AddItem(CWRank4RewardSons) + Else + log("CWScript", "setPlayerFactionRank() expected RankToSetTo to be 1,2,3 or 4. Instead got:" + RankToSetTo, 2, True) + EndIf + + Else + + log("CWScript", "setPlayerFactionRank() expected PlayerAllegiance to be 1, or 2. Instead got:" + PlayerAllegiance, 2, True) + + EndIf + + + +EndFunction + +function RewardPlayerForReclaimingHold() + if PlayerAllegiance == iImperials + Game.GetPlayer().AddItem(CWRank2RewardImperial) + Elseif PlayerAllegiance == iSons + Game.GetPlayer().AddItem(CWRank2RewardSons) + Else + log("CWScript", "RewardPlayerForReclaimingHold() expected PlayerAllegiance to be 1, or 2. Instead got:" + PlayerAllegiance, 2, True) + + EndIf + +EndFunction + +function SetSoldierAliasDialogueFactions(ReferenceAlias SoldierAlias, bool AddToWaitingToAttack = False, bool AddToWaitingToDefend = False) +{Adds the passed in Alias's actor to the appropriate CWDialogueSoldierWaitingToAttack/DefendFaction.} + + Actor SoldierActor = SoldierAlias.GetActorReference() + + log("CWScript", "SetSoldierAliasDialogueFactions() adding " + SoldierActor + " to faction CWDialogueSoldierFaction") + + ;Always add to the soldier dialogue faction: + SoldierActor.AddToFaction(CWDialogueSoldierFaction) + + if AddToWaitingToAttack + log("CWScript", "SetSoldierAliasDialogueFactions() adding " + SoldierActor + " to faction CWDialogueSoldierWaitingToAttackFaction") + SoldierActor.AddToFaction(CWDialogueSoldierWaitingToAttackFaction) + EndIf + + if AddToWaitingToDefend + log("CWScript", "SetSoldierAliasDialogueFactions() adding " + SoldierActor + " to faction CWDialogueSoldierWaitingToDefendFaction") + SoldierActor.AddToFaction(CWDialogueSoldierWaitingToDefendFaction) + EndIf + + +EndFunction + +Function ContributeToSalaryPool() + if PlayerRank == 0 + salary += (BaseSalary) as int + elseif PlayerRank == 1 + salary += (BaseSalary * SalaryMultRank1) as int + elseif PlayerRank == 2 + salary += (BaseSalary * SalaryMultRank2) as int + elseif PlayerRank == 3 + salary += (BaseSalary * SalaryMultRank3) as int + elseif PlayerRank >= 4 + salary += (BaseSalary * SalaryMultRank4) as int + EndIf + +EndFunction + +function paySalary() +{Pay player a salary after campaign based on his rank} + Game.GetPlayer().AddItem(Gold001, salary) + salary = 0 +EndFunction + +Function donateSalary() +{player has donated his salary to the cause... right now this is just flavor, we may want it to contribute something to the attack delta, increase favor points, etc.} + salary = 0 +EndFunction + +ObjectReference Function GetFactionHQMarkerForActor(Actor ActorToCheck) +{Returns the marker in the alias corresponding to the FactionHQ based on whether the actor is in CWImperialFaction or CWSonsFaction.} +;Used by CWEscapeCityEscapeDoorScript on EscapeDoor alias in CWEscapeCity Quest + int ActorFaction = GetActorAllgeiance(ActorToCheck) + + ObjectReference FactionHQMarker + + if ActorFaction == iImperials + FactionHQMarker = ImperialFactionHQMarker.GetReference() + + elseif ActorFaction == iSons + FactionHQMarker = SonsFactionHQMarker.GetReference() + Else + log("CWScript", " WARNING: GetFactionHQForActor() can't determine which faction this actor belongs to:" + ActorToCheck, 2) + EndIf + + log("CWScript", "GetFactionHQForActor(" + ActorToCheck + ") returning " + FactionHQMarker) + + return FactionHQMarker + +EndFunction + + +ObjectReference Function GetExiledMarkerForActor(Actor ActorToCheck) +{Returns the marker in the alias corresponding to the ExiledMarker based on whether the actor is in GovImperial or GovSons factions.} +;Used by CWEscapeCityEscapeDoorScript on EscapeDoor alias in CWEscapeCity Quest +;NOTE THIS DUPLICATES SOME FUNCTIONALITY ALSO FOUND IN CWGovernmentScript and CWGovernment quest. + + ObjectReference ExileMarker + + if ActorToCheck.IsInFaction(GovImperial) + ExileMarker = ExiledImperialMarker.GetReference() + + elseif ActorToCheck.IsInFaction(GovSons) + ExileMarker = ExiledSonsMarker.GetReference() + Else + log("CWScript", " WARNING: GetExiledMarkerForActor() can't determine which faction this actor belongs to:" + ActorToCheck, 2) + EndIf + + log("CWScript", "GetExiledMarkerForActor(" + ActorToCheck + ") returning " + ExileMarker) + + return ExileMarker + +EndFunction + +function StartCWCitizensFlee(Location LocationOfBattle) + log("CWScript", "StartCWCitizensFlee(" + LocationOfBattle + ")") + + int waitTime = 0 + bool bailOut = False + + if CWCitizensFlee.IsStopped() == False + log("CWScript", " WARNING: StartCWCitizensFlee() the CWCitizensFlee quest is currently running, stopping it and starting a new one." , 2, true, true) + + CWCitizensFlee.Stop() + + while CWCitizensFlee.IsStopped() == false && bailOut == False + log("CWScript", " WARNING: StartCWCitizensFlee() the CWCitizensFlee quest is currently running, waiting for it to stop completely. Have been waiting for " +waitTime , 1) + utility.wait(1) + + waitTime +=1 + + if waitTime > 30 + + log("CWScript", " WARNING: StartCWCitizensFlee() the CWCitizensFlee quest is currently running, have been waiting too long. Bailing out." , 1) + bailOut = True + + EndIf + + EndWhile + + EndIf + + CWCitizensFleeStart.SendStoryEvent(LocationOfBattle) + + +EndFunction + +function StopCWCitizensFlee() + log("CWScript", "StopCWCitizensFlee() calling Stop() on CWCitizensFlee quest") + CWCitizensFlee.Stop() + +EndFunction + +function Persuade(Actor Target) +{Calls the favor script function} + log("CWScript", "Persuade(" + Target + ") calling Persuade() on DialogueFavorGeneric quest's FavorDialogueScript") + DialogueFavorGenericS.Persuade(Target) + +EndFunction + +function Bribe(Actor Target) +{Calls the favor script function} + log("CWScript", "Bribe(" + Target + ") calling Bribe() on DialogueFavorGeneric quest's FavorDialogueScript") + DialogueFavorGenericS.Bribe(Target) + +EndFunction + +function Intimidate(Actor Target) +{Calls the favor script function} + log("CWScript", "Intimidate(" + Target + ") calling Intimidate() on DialogueFavorGeneric quest's FavorDialogueScript") + DialogueFavorGenericS.Intimidate(Target) + +EndFunction + +function Brawl(Actor Target) +{Calls the favor script function} + log("CWScript", "Brawl(" + Target + ") calling Brawl() on DialogueFavorGeneric quest's FavorDialogueScript") + DialogueFavorGenericS.Brawl(Target) + +EndFunction + +function GiveGift(Actor Target) +{Calls the favor script function} + log("CWScript", "GiveGift(" + Target + ") calling GiveGift() on DialogueFavorGeneric quest's FavorDialogueScript") + DialogueFavorGenericS.GiveGift(Target) + +EndFunction + +function ToggleOffComplexWIInteractions(LocationAlias LocationAliasToToggle) + Log("CWMissionScript", self + "ToggleOffComplexWIInteractions(" + LocationAliasToToggle + ") calling function on WIFunctionScript") + WIs.DisallowComplexInteractions(LocationAliasToToggle.GetLocation()) + +EndFunction + +function ToggleOnComplexWIInteractions(LocationAlias LocationAliasToToggle) + Log("CWMissionScript", self + "ToggleOnComplexWIInteractions(" + LocationAliasToToggle + ") calling function on WIFunctionScript") + WIs.AllowComplexInteractions(LocationAliasToToggle.GetLocation()) + +EndFunction + +function ToggleOffWIDragons(LocationAlias LocationAliasToToggle) + Log("CWMissionScript", self + "ToggleOffWIDragons(" + LocationAliasToToggle + ") calling function on WIFunctionScript") + WIs.DisallowDragons(LocationAliasToToggle.GetLocation()) + +EndFunction + +function ToggleOnWIDragons(LocationAlias LocationAliasToToggle) + Log("CWMissionScript", self + "ToggleOnWIDragons(" + LocationAliasToToggle + ") calling function on WIFunctionScript") + WIs.AllowDragons(LocationAliasToToggle.GetLocation()) + +EndFunction + + + + + + + + + +;************************************************************************************************************ +;*********************************** OBSOLETE FUNCTIONS ***************************************************** +;************************************************************************************************************ +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** +;*** + + + + Function OutputXMLRowOpenTag(string RowName) + log("CWScript", "CW XML: <" + RowName + ">" ) +EndFunction + + Function OutputXMLRowCloseTag(string RowName) + log("CWScript", "CW XML: " ) +EndFunction + + Function OutputXMLField(string FieldName, string fieldValue) + log("CWScript", "CW XML: <" + FieldName + ">" + fieldValue + "" ) +EndFunction + +Function OutputCampaignStatsXMLRow() + ;NOTE: You'll need to a) filter the warnings for "CW xml:" + ;b) remove "[Timestamp] CW XML:" from each line, + ;c) add tag at head and foot of document + + + OutputXMLRowOpenTag("CampaignStats") + + outputCampaignStatsXMLRowA() + outputCampaignStatsXMLRowB() + + OutputXMLRowCloseTag("CampaignStats") + +EndFunction + +; to get around large function compiler bug. These should go back inside the maine outputCampaignStatsXMLRow function when that bug is fixed +Function outputCampaignStatsXMLRowA() + OutputXMLField("countCampaigns", countCampaigns as string) + + OutputXMLField("ContestedHold", HoldName(ContestedHold)) + OutputXMLField("Attacker", FactionName(Attacker)) + OutputXMLField("Defender", FactionName(Defender)) + + OutputXMLField("OwnerHaafingar", FactionName(OwnerHaafingar)) + OutputXMLField("OwnerReach", FactionName(OwnerReach)) + OutputXMLField("OwnerHjaalmarch", FactionName(OwnerHjaalmarch)) + OutputXMLField("OwnerWhiterun", FactionName(OwnerWhiterun)) + OutputXMLField("OwnerFalkreath", FactionName(OwnerFalkreath)) + OutputXMLField("OwnerPale", FactionName(OwnerPale)) + OutputXMLField("OwnerWinterhold", FactionName(OwnerWinterhold)) + OutputXMLField("OwnerEastmarch", FactionName(OwnerEastmarch)) + OutputXMLField("OwnerRift", FactionName(OwnerRift)) +EndFunction + + +Function outputCampaignStatsXMLRowB() + OutputXMLField("countWinImperials", countWinImperials as string) + OutputXMLField("countWinSons", countWinSons as string) + OutputXMLField("countWinReachImperials", countWinReachImperials as string) + OutputXMLField("countWinReachSons", countWinReachSons as string) + OutputXMLField("countWinHjaalmarchImperials", countWinHjaalmarchImperials as string) + OutputXMLField("countWinHjaalmarchSons", countWinHjaalmarchSons as string) + OutputXMLField("countWinWhiterunImperials", countWinWhiterunImperials as string) + OutputXMLField("countWinWhiterunSons", countWinWhiterunSons as string) + OutputXMLField("countWinFalkreathImperials", countWinFalkreathImperials as string) + OutputXMLField("countWinFalkreathSons", countWinFalkreathSons as string) + OutputXMLField("countWinPaleImperials", countWinPaleImperials as string) + OutputXMLField("countWinPaleSons", countWinPaleSons as string) + OutputXMLField("countWinWinterholdImperials", countWinWinterholdImperials as string) + OutputXMLField("countWinWinterholdSons", countWinWinterholdSons as string) + OutputXMLField("countWinRiftImperials", countWinRiftImperials as string) + OutputXMLField("countWinRiftSons", countWinRiftSons as string) +EndFunction +; + +function resetStrengthPoints() +{Clears the strHOLDImperial/Sons properties.} + strHaafingarImperial = 0 + strHaafingarSons = 0 + strReachImperial = 0 + strReachSons = 0 + strHjaalmarchImperial = 0 + strHjaalmarchSons = 0 + strWhiterunImperial = 0 + strWhiterunSons = 0 + strFalkreathImperial = 0 + strFalkreathSons = 0 + strPaleImperial = 0 + strPaleSons = 0 + strWinterholdImperial = 0 + strWinterholdSons = 0 + strEastmarchImperial = 0 + strEastmarchSons = 0 + strRiftImperial = 0 + strRiftSons = 0 + + EndFunction + + function setStrengthPoints() +{Sets the strXXXHoldImperials strXXXHoldSons values for all the holds for each faction.} + + ;clear properties + resetStrengthPoints() + + ;these next functions are broken into seperate functions rather than living directly in this function to get around a bug running large functions in game. I probably will leave it this way even after the bug is fixed. + setStrengthPointsHaafingar() + setStrengthPointsReach() + setStrengthPointsHjaalmarch() + setStrengthPointsWhiterun() + setStrengthPointsFalkreath() + setStrengthPointsPale() + setStrengthPointsWinterhold() + setStrengthPointsEastmarch() + setStrengthPointsRift() + +EndFunction + +; +;Note for self: +;These functions setSrengthPointsHOLDxxx() functions exist solely to get around a bug dealing with a long function. They all used to live in the setStrengthPoints() function. Once that bug is dealt with, I could copy these back into that function. But that won't serve much purpose. +;If I had an array, I could set up arrays for adjacent hold data, and then abstract these into a single function. But I'm not sure when/if we'll get arrays in the scripting language +function setStrengthPointsHaafingar() + ;Haafingar -- adj holds = Reach, Hjaalmarch + if OwnerHaafingar == iImperials + strReachImperial = strReachImperial + StrValueHaafingar + strHjaalmarchImperial = strHjaalmarchImperial + StrValueHaafingar + else ;owner is iSons + strReachSons = strReachSons + StrValueHaafingar + strHjaalmarchSons = strHjaalmarchSons + StrValueHaafingar + endif +EndFunction + +function setStrengthPointsReach() + ;Reach -- adj holds = Haafingar, Hjaalmarch, Whiterun, Falkreath + if OwnerReach == iImperials + strHaafingarImperial = strHaafingarImperial + StrValueReach + strHjaalmarchImperial = strHjaalmarchImperial + StrValueReach + strWhiterunImperial = strWhiterunImperial + StrValueReach + strFalkreathImperial = strFalkreathImperial + StrValueReach + else ;owner is iSons + strHaafingarSons = strHaafingarSons + StrValueReach + strHjaalmarchSons = strHjaalmarchSons + StrValueReach + strWhiterunSons = strWhiterunSons + StrValueReach + strFalkreathSons = strFalkreathSons + StrValueReach + endif +EndFunction + +function setStrengthPointsHjaalmarch() + ;Hjaalmarch -- adj holds = Haafingar, Reach, Whiterun, Pale + if OwnerHjaalmarch == iImperials + strHaafingarImperial = strHaafingarImperial + StrValueHjaalmarch + strReachImperial = strReachImperial + StrValueHjaalmarch + strWhiterunImperial = strWhiterunImperial + StrValueHjaalmarch + strPaleImperial = strPaleImperial + StrValueHjaalmarch + else ;owner is iSons + strHaafingarSons = strHaafingarSons + StrValueHjaalmarch + strReachSons = strReachSons + StrValueHjaalmarch + strWhiterunSons = strWhiterunSons + StrValueHjaalmarch + strPaleSons = strPaleSons + StrValueHjaalmarch + endif +endFunction + +function setStrengthPointsWhiterun() + ;Whiterun -- adj holds = Reach, Hjaalmarch, Falkreath, Pale, Eastmarch, Rift + if OwnerWhiterun== iImperials + strReachImperial = strReachImperial + StrValueWhiterun + strHjaalmarchImperial = strHjaalmarchImperial + StrValueWhiterun + strFalkreathImperial = strFalkreathImperial + StrValueWhiterun + strPaleImperial = strPaleImperial + StrValueWhiterun + strEastmarchImperial = strEastmarchImperial + StrValueWhiterun + strRiftImperial = strRiftImperial + StrValueWhiterun + else ;owner is iSons + strReachSons = strReachSons + StrValueWhiterun + strHjaalmarchSons = strHjaalmarchSons + StrValueWhiterun + strFalkreathSons = strFalkreathSons + StrValueWhiterun + strPaleSons = strPaleSons + StrValueWhiterun + strEastmarchSons = strEastmarchSons + StrValueWhiterun + strRiftSons = strRiftSons + StrValueWhiterun + endif +EndFunction + +function setStrengthPointsFalkreath() + ;Falkreath -- adj holds = Reach, Whiterun, Rift + if OwnerFalkreath== iImperials + strReachImperial = strReachImperial + StrValueFalkreath + strWhiterunImperial = strWhiterunImperial + StrValueFalkreath + strRiftImperial = strRiftImperial + StrValueFalkreath + else ;owner is iSons + strReachSons = strReachSons + StrValueFalkreath + strWhiterunSons = strWhiterunSons + StrValueFalkreath + strRiftSons = strRiftSons + StrValueFalkreath + endif +EndFunction + +function setStrengthPointsPale() + ;Pale -- adj holds = Hjaalmarch, Whiterun, Winterhold, Eastmarch + if OwnerPale == iImperials + strHjaalmarchImperial = strHjaalmarchImperial + StrValuePale + strWhiterunImperial = strWhiterunImperial + StrValuePale + strWinterholdImperial = strWinterholdImperial + StrValuePale + strEastmarchImperial = strEastmarchImperial + StrValuePale + else ;owner is iSons + strHjaalmarchSons = strHjaalmarchSons + StrValuePale + strWhiterunSons = strWhiterunSons + StrValuePale + strWinterholdSons = strWinterholdSons + StrValuePale + strEastmarchSons = strEastmarchSons + StrValuePale + endif +EndFunction + +function setStrengthPointsWinterhold() + ;Winterhold -- adj holds = Pale, Eastmarch + if OwnerWinterhold == iImperials + strPaleImperial = strPaleImperial + StrValueWinterhold + strEastmarchImperial = strEastmarchImperial + StrValueWinterhold + else ;owner is iSons + strPaleSons = strPaleSons + StrValueWinterhold + strEastmarchSons = strEastmarchSons + StrValueWinterhold + endif +EndFunction + +function setStrengthPointsEastmarch() + ;Eastmarch -- adj holds = Winterhold, Pale, Whiterun, Rift + if OwnerEastmarch == iImperials + strWinterholdImperial = strWinterholdImperial + StrValueEastmarch + strPaleImperial = strPaleImperial + StrValueEastmarch + strWhiterunImperial = strWhiterunImperial + StrValueEastmarch + strRiftImperial = strRiftImperial + StrValueEastmarch + else ;owner is iSons + strWinterholdSons = strWinterholdSons + StrValueEastmarch + strPaleSons = strPaleSons + StrValueEastmarch + strWhiterunSons = strWhiterunSons + StrValueEastmarch + strRiftSons = strRiftSons + StrValueEastmarch + endif +EndFunction + +function setStrengthPointsRift() + ;Rift -- adj holds = Whiterun, Falkreath, Eastmarch + if OwnerRift == iImperials + strWhiterunImperial = strWhiterunImperial + StrValueRift + strFalkreathImperial = strFalkreathImperial + StrValueRift + strEastmarchImperial = strEastmarchImperial + StrValueRift + else ;owner is iSons + strWhiterunSons = strWhiterunSons + StrValueRift + strFalkreathSons = strFalkreathSons + StrValueRift + strEastmarchSons = strEastmarchSons + StrValueRift + endif +EndFunction +; + +function StartNewCampaign() +{Sets Attacker, Defender, Contested Hold, and strHOLDXXX properties.} + + log("CWScript", "StartNewCampagin() will set CWScript properties for new campaign.") + + SetStrengthPoints() + attacker = ChooseAttackingFaction(CWDebugForceAttacker.Value as int) + if attacker == iImperials + defender = iSons + Else + defender = iImperials + EndIf + + ;set the CWAttacker and CWDefender globals for use in condition functions where you want to check against their value + CWAttacker.value = attacker + CWDefender.value = defender + + contestedHold = ChooseHoldToAttack(attacker, CWDebugForceHold.value as int) + CWContestedHold.value = contestedHold + setAttackDelta() + purchaseDelta = AttackDelta + countCampaigns += 1 + + log("CWScript", "StartNewCampagin() finished setting CWScript properties for new campaign.") + log("CWScript", "StartNewCampagin() Attacker=" + Attacker + ", Defender=" + Defender + ", ContestedHold=" + ContestedHold + ", AttackDelta=" +AttackDelta) + + if DebugDBTraces == 1 + outputCampaignStatsXMLRow() + endif + + ;Start the campaign quest + if debugForceOffscreenResult == 0 + startCampaignQuest(ContestedHold) + + Else ;we are in forced offscreen mode + resolveOffscreen() + + EndIf + +EndFunction + + + + +int Function GetStrengthPoints(int FactionToCheck, int HoldToCheck) +{Returns an int specifying the strength points of the FactionToCheck (1 = Imperial, 2 = Sons) in HoldToCheck(1-9), -1 = FAIL} + int strImperial ;the strength points of the faction in the hold + int strSons ;the strength points of the faction in the hold + + ;get each factions strength points for the hold in question + if HoldToCheck == iHaafingar ;1 + strImperial = strHaafingarImperial + strSons = strHaafingarSons + elseif HoldToCheck == iReach ; 2 + strImperial = strReachImperial + strSons = strReachSons + elseif HoldToCheck == iHjaalmarch ;3 + strImperial = strHjaalmarchImperial + strSons = strHjaalmarchSons + elseif HoldToCheck == iWhiterun ;4 + strImperial = strWhiterunImperial + strSons = strWhiterunSons + elseif HoldToCheck == iFalkreath ;5 + strImperial = strFalkreathImperial + strSons = strFalkreathSons + elseif HoldToCheck == iPale ;6 + strImperial = strPaleImperial + strSons = strPaleSons + elseif HoldToCheck == iWinterhold ;7 + strImperial = strWinterholdImperial + strSons = strWinterholdSons + elseif HoldToCheck == iEastmarch ;8 + strImperial = strEastmarchImperial + strSons = strEastmarchSons + elseif HoldToCheck == iRift ;9 + strImperial = strRiftImperial + strSons = strRiftSons + else + log("CWScript", "GetStrengthPoints() HoldToCheck parametered unrecognized. Expected an int 1-9: got " + HoldToCheck) + return -1 + EndIf + + ;return the strength points of the hold for the faction in question + If FactionToCheck == iImperials + return strImperial + ElseIf FactionToCheck == iSons + return strSons + Else + log("CWScript", "GetStrengthPoints() FactionToCheck parameter unrecognized. Expected 1 or 2: got " + FactionToCheck) + return -1 + EndIf + +EndFunction + + +int Function ChooseAttackingFaction(int FactionToForce = 0) +{Returns an int representing a random faction to be the attacker in the next campaign, unless rules dictate the attacker should be forced to a particular faction.} + + int ChosenFaction = FactionToForce + + previousAttacker = attacker ;set the previous attacker + + log("CWScript", "ChooseAttackingFaction() FactionToForce =" +FactionToForce) + + ;if either factions owns all the contestable holds, force the attacker to the other faction + if FactionOwnsAll(iImperials) + ChosenFaction = iSons + log("CWScript", "Imperials own all, forcing attacker to be Sons") + + ElseIf FactionOwnsAll(iSons) + ChosenFaction = iImperials + log("CWScript", "Sons own all, forcing attacker to be Imperials") + + ;If either side has attacked more than the allowable # of attacks, force the other side + ElseIf ConsecutiveAttacks > CWMaxConsecutiveAttacks.value ;this is a global so we can more easily tweak this setting as we play + if PreviousAttacker == iImperials + ChosenFaction = iSons + Else ;Previous attacker was iSons + ChosenFaction = iImperials + EndIf + + ConsecutiveAttacks = 0 + log("CWScript", "ConsecutiveAttacks > CWMaxConsecutiveAttacks.value, forcing attacker to be " + FactionName(ChosenFaction)) + + ElseIf ChosenFaction == 0 ;we aren't forcing it + ChosenFaction = utility.RandomInt(1,2) ;1 = Imperials, 2 = Sons + EndIf + + if previousAttacker == ChosenFaction + consecutiveAttacks += 1 + EndIf + + log("CWScript", "ChooseAttackingFaction() is returning " + ChosenFaction + "(" + FactionName(ChosenFaction) + ")") + return ChosenFaction +EndFunction + + +int Function ValidateHoldToAttack(int Hold, int HoldOwner, int AttackingFaction, int AttackerStengthPoints) +{Sub function for ChooseHoldToAttack, returns an int with the failure code, or 0 if there is no failure } + ;VERIFY this is a valid Hold to attack. Otherwise, FAILURE: 1 = impossible to attack this hold (Haafingar/Eastmarch), 2 = Attacker already owns, 3 = Attacker owns no adjacent holds + ;Check for non-contestable holds + + int failure = 0 + + if (Hold == iHaafingar) || (Hold == iEastmarch) && CWDebugAllowCampaignsInFinalHolds.GetValue() == 0 + ;FAIL + failure = 1 + log("CWScript", "ChooseHoldToAttack tried to attack Haafingar or Eastmarch.") + + elseif AttackingFaction == HoldOwner + ;FAIL + failure = 2 + log("CWScript", "ChooseHoldToAttack tried to attack a hold already owned by the AttackingFaction.") + + elseif AttackerStengthPoints == 0 + ;FAIL + failure = 3 + log("CWScript", "ChooseHoldToAttack tried to attack a hold where attacking faction has no AttackPoints in hold (owns no adjacent holds).") + + Else + ;SUCCESS!! + log("CWScript", "ChooseHoldToAttack picked a valid hold to attack (" + HoldName(Hold) +").") + + EndIf + + return failure + + +EndFunction + +int Function ChooseHoldToAttack(int AttackingFaction, int HoldToForce = 0) +{Takes int AttackingFaction (1 = Imperials, 2 = Sons). It SETS various PROPERTIES and RETURNS an INT corresponding to the hold that should be attacked next. -1 == FAIL} + ;param int AttackingFaction Which faction is attacking? 1 = Imperials, 2 = Sons + ;param int HoldToForce Default = 0; sets Hold to this value + + bool FoundHold ;0 = keep trying, 1 = found a hold that passed the validity check, return HoldToAttack + int Hold ;1-9 = which hold to attack (if valid) + int HoldOwner ;who owns the hold? 1 = Imperials, 2 = Sons + int strImperials ;the strength points of the Imperials in the hold + int strSons ;the strength points of the Sons in the hold + int StrAtkr ;the strength points of the attacker + int strDfdr ;the strength points of the defender + + int failure ;1 = impossible to attack this hold (Haafingar/Eastmarch), 2 = Attacker already owns, 3 = Attacker owns no adjacent holds + + + int TriesLeftBeforeAllowingPreviousContestedHold = 5 ;try to pick something else, if nothing else is valid, go ahead and pick the same hold as last campaign, counts down multiple attempts before giving up - see "While FoundHold == 0" loop below + + ;set the previousContestedHold -- note is redundant. It is set in FinishCampaign() but setting it again shouldn't hurt. + previousContestedHold = contestedHold + + If HoldToForce > 0 + log("CWScript", "Running chooseHoldToAttack() with HoldToForce =" + HoldToForce + ". ") + Hold = HoldToForce + EndIf + + While FoundHold == 0 + + ;If we haven't rolled for a hold yet, roll a 9 sided die (for 9 holds to try) + if Hold == 0 + Hold = utility.randomInt(1,9) + + EndIf + + log("CWScript", "ChooseHoldToAttack Attacking faction =" + AttackingFaction + "(" + FactionName(AttackingFaction)+ ")") + + log("CWScript", "ChooseHoldToAttack chose hold # " + Hold + "(" + HoldName(Hold) +")") + + HoldOwner = GetHoldOwner(Hold) + + log("CWScript", "ChooseHoldToAttack HoldOwner =" + HoldOwner + "(" +FactionName(HoldOwner) + ")") + + strImperials = GetStrengthPoints(iImperials, Hold) + + log("CWScript", "ChooseHoldToAttack strImperials =" + strImperials) + + strSons = GetStrengthPoints(iSons, Hold) + + log("CWScript", "ChooseHoldToAttack strSons =" + strSons) + + ;Establish the attacker/defender strength points + if AttackingFaction == iImperials + strAtkr = strImperials + strDfdr = strSons + + elseif AttackingFaction == iSons + strAtkr = strSons + strDfdr = strImperials + + Else + log("CWScript", "ChooseHoldToAttack expecting 1 or 2 for AttackingFaction parameter. Got " + AttackingFaction + " this will break the civil war system.") + debug.MessageBox("ChooseHoldToAttack expecting 1 or 2 for AttackingFaction parameter. Got " + AttackingFaction + " this will break the civil war system.") + return -1 + EndIf + + ;VERIFY this is a valid Hold to attack. Otherwise, FAILURE: 1 = impossible to attack this hold (Haafingar/Eastmarch), 2 = Attacker already owns, 3 = Attacker owns no adjacent holds + failure = ValidateHoldToAttack(Hold, HoldOwner, AttackingFaction, strAtkr) + + if failure > 0 && !(failure == 3 && debugAllowNonAdjacentHolds == 1) ;if we have a failure that a debug variable isn't allowing + FoundHold = 0 + Hold = 0 + Failure = 0 + + log("CWScript", "ChooseHoldToAttack picked an invalid hold, re-rolling a new hold to try to attack.") + + elseif Hold == previousContestedHold && TriesLeftBeforeAllowingPreviousContestedHold > 0 + TriesLeftBeforeAllowingPreviousContestedHold -= 1 + FoundHold = 0 + Hold = 0 + + log("CWScript", "ChooseHoldToAttack picked the previously contested hold, re-rolling a new hold to try to attack. Tries left before allowing previous hold: " + TriesLeftBeforeAllowingPreviousContestedHold) + + else ;success + + if failure == 3 && debugAllowNonAdjacentHolds == 1 + log("CWScript", "ChooseHoldToAttack() Ignoring Adjacent Hold requirement and allowing the attack.", 1) + endif + + ;SET CWSCRIPT PROPERTIES + ContestedHold = Hold + OwnerContestedHold = HoldOwner + strContestedHoldImperial = strImperials + strContestedHoldSons = strSons + strAttacker = strAtkr + strDefender= strDfdr + + FoundHold = 1 + return hold + endif + + EndWhile + + +EndFunction + + +Function SetAttackDelta() +{Sets the attack delta based on current strAttacker and strDefender} + AttackDelta = strAttacker - strDefender + + log("CWScript", "AttackDelta (" + AttackDelta + " ) = StrAttack (" + StrAttacker + ") - StrDefender (" + StrDefender + ")") + + if Math.abs(AttackDelta) > MaxAttackDelta + if AttackDelta > 0 + AttackDelta = MaxAttackDelta + Else + AttackDelta = -MaxAttackDelta + endif + + log("CWScript", "|AttackDelta| is larger than MaxAttackDelta, constraining AttackDelta(" + AttackDelta + ") to MaxAttackDelta (" + MaxAttackDelta + ")") + EndIf + +EndFunction + + +Function startCampaignQuest(int Hold) +{Starts CWCampaign using CWCampaignStart.SendStoryEvent() with the corresponding Location of the ContestedHold} + location CampaignLocation = GetLocationForHold(Hold) + ObjectReference CampaignStartMarker = GetCampaignStartMarker(Hold) + + CWCampaignStart.SendStoryEvent(CampaignLocation,CampaignStartMarker) + + log("CWScript", "startCampaignQuest: CWCampainStart.SendStoryEvent(" + CampaignLocation + ", " + CampaignStartMarker+ ")") + + +EndFunction + +;OLD VERSION +;Function SetHoldOwner(int HoldToSet, int FactionToOwn) +;{Takes int HoldToSet and int FactionToOwn, and calls the appropriate setOwnerXXX(FactionToOwn) function} +; +; if HoldToSet == iHaafingar ;1 +; setOwnerHaafingar(FactionToOwn) +; +; elseif HoldToSet == iReach ; 2 +; setOwnerReach(FactionToOwn) +; +; elseif HoldToSet == iHjaalmarch ;3 +; setOwnerHjaalmarch(FactionToOwn) +; +; elseif HoldToSet == iWhiterun ;4 +; setOwnerWhiterun(FactionToOwn) +; +; elseif HoldToSet == iFalkreath ;5 +; setOwnerFalkreath(FactionToOwn) +; +; elseif HoldToSet == iPale ;6 +; setOwnerPale(FactionToOwn) +; +; elseif HoldToSet == iWinterhold ;7 +; setOwnerWinterhold(FactionToOwn) +; +; elseif HoldToSet == iEastmarch ;8 +; setOwnerEastmarch(FactionToOwn) +; +; elseif HoldToSet == iRift ;9 +; setOwnerRift(FactionToOwn) +; +; else +; log("CWScript", "SetHoldOwner(" + HoldToSet + ") parametered unrecognized. Expected an int 1-9 as HoldToCheck, got something else.") +; EndIf +; +;EndFunction + +function finishCampaign() +{Sets properties, and other campaign clean up duties... called by CWCampaign stage 255} + + ;set properties appropriately + CampaignRunning = 0 ;not running -- this used to happen in the CWCampaign shut down stage. It lives here so that we are sure the faction leader won't have dialogue talking about the campaign that is just finishing up + + CWCampaignS.completedMission = 0 ;clear out so Field CO doesn't say anything about a completed mission from previous campaign + CWCampaignS.failedMission = 0 ;clear out so Field CO doesn't say anything about a failed mission from previous campaign + + (CWCampaign as CWCampaignScript).stopTutorialMission() + + setContestedHoldWinType() + setCountWins() + previousContestedHold = contestedHold ;note this is also set in StartCampaign() but setting it again shouldn't hurt. It needs to go here so that Faction leader has something to say when you report in + + ;Show messages, objectives, and stop CampaignQuest + if debugForceOffscreenResult == 0 + + playerReport = 1 ;player needs to report to faction leader + + ;Show the campaign won message: + getCampaignWonMessage().show() + + if contestedHoldWinner == playerAllegiance + CWCampaignObj.setStage(20) ;objective: report success + else + CWCampaignObj.setStage(30) ;objective: report failure + endif + + EndIf + + ContributeToSalaryPool() + +;USES OLD COMMENTED OUT VERSION +; setHoldOwner(ContestedHold, ContestedHoldWinner) ;we should set objectives before this, but also this needs to be called before stopping the campaign so the new one doesn't try to start before it knows who the new owner is + + if debugForceOffscreenResult == 0 + log("CWScript", "CWCampaign: stopping quest, campaign finished.") + + CWCampaign.stop() + endif + + +EndFunction + + +Function SetGarrisonCost(Location LocToSet, int Cost) +{Takes Location LocToSet and sets its CWCost keyword data to Int Cost} + LocToSet.SetKeywordData(CWCost, Cost) + log("CWScript", "SetGarrisonCost() Location =" + LocToSet + ", Cost = " + Cost) + +EndFunction + +int Function GetGarrisonCost(Location LocToGetCost) + int cost = LocToGetCost.GetKeywordData(CWCost) as Int + log("CWScript", "GetGarrisonCost() Location =" + LocToGetCost + ", Cost = " + Cost) + return cost + +EndFunction + + +Function setInitialCosts() +{Called in the OnInit block, one time set up of initial Costs of all the locations.} + + ;Have to break this into sub functions to get around with a compiler bug with complex functions + setInitialGarrisonCostsHaafingar() + setInitialGarrisonCostsReach() + setInitialGarrisonCostsHjaalmarch() + setInitialGarrisonCostsWhiterun() + setInitialGarrisonCostsFalkreath() + setInitialGarrisonCostsPale() + setInitialGarrisonCostsWinterhold() + setInitialGarrisonCostsEastmarch() + setInitialGarrisonCostsRift() + +EndFunction + +;setInitialCosts() subfunctions -- to get around a function size bug in the compiler +Function setInitialGarrisonCostsHaafingar() + SetGarrisonCost(SolitudeLocation, iCostNonContestable) + SetGarrisonCost(SolitudeSawmillLocation, iCostNonContestable) + SetGarrisonCost(KatlasFarmLocation, iCostNonContestable) + SetGarrisonCost(DragonBridgeLocation, iCostNonContestable) + + SetGarrisonCost(FortHraggstadLocation, iCostNonContestable) +EndFunction + +Function setInitialGarrisonCostsReach() + SetGarrisonCost(MarkarthLocation, iCostNonContestable) + SetGarrisonCost(CidhnaMineLocation, iCostNonContestable) + SetGarrisonCost(LeftHandMineLocation, iCostNonContestable) + SetGarrisonCost(SalviusFarmLocation, iCostNonContestable) + SetGarrisonCost(KarthwastenLocation, iCostMedium) + SetGarrisonCost(OldHroldanLocation, iCostMedium) + SetGarrisonCost(KolskeggrMineLocation, iCostSmall) + + SetGarrisonCost(FortSungardLocation, iCostFort) +EndFunction + +Function setInitialGarrisonCostsHjaalmarch() + SetGarrisonCost(MorthalLocation, iCostNonContestable) + SetGarrisonCost(StonehillsLocation, iCostSmall) +; SetGarrisonCost(FrostRiverFarmLocation, iCostSmall) + + SetGarrisonCost(FortSnowhawkLocation, iCostFort) +EndFunction + +Function setInitialGarrisonCostsWhiterun() + SetGarrisonCost(WhiterunLocation, iCostNonContestable) + SetGarrisonCost(BattleBornFarmLocation, iCostNonContestable) + SetGarrisonCost(ChillfurrowFarmLocation, iCostNonContestable) + SetGarrisonCost(PelagiaFarmLocation, iCostNonContestable) + SetGarrisonCost(RoriksteadLocation, iCostMedium) + SetGarrisonCost(RiverwoodLocation, iCostSmall) +; SetGarrisonCost(BarleydarkFarmLocation, iCostSmall) + + SetGarrisonCost(FortGreymoorLocation, iCostFort) +EndFunction + +Function setInitialGarrisonCostsFalkreath() + SetGarrisonCost(FalkreathLocation, iCostNonContestable) +; SetGarrisonCost(GraniteHillLocation, iCostMedium) + SetGarrisonCost(HelgenLocation, iCostMedium) +; SetGarrisonCost(BearsCaveMillLocation, iCostSmall) + SetGarrisonCost(HalfmoonMillLocation, iCostSmall) + + SetGarrisonCost(FortNeugradLocation, iCostFort) +EndFunction + +Function setInitialGarrisonCostsPale() + SetGarrisonCost(DawnstarLocation, iCostNonContestable) +; SetGarrisonCost(HeljarchenLocation, iCostMedium) + SetGarrisonCost(AngasMillLocation, iCostSmall) + SetGarrisonCost(LoreiusFarmLocation, iCostSmall) + + SetGarrisonCost(FortDunstadLocation, iCostFort) +EndFunction + +Function setInitialGarrisonCostsWinterhold() + SetGarrisonCost(WinterholdLocation, iCostNonContestable) + SetGarrisonCost(WhistlingMineLocation, iCostSmall) + + SetGarrisonCost(FortKastavLocation, iCostFort) +EndFunction + +Function setInitialGarrisonCostsEastmarch() + SetGarrisonCost(WindhelmLocation, iCostNonContestable) + SetGarrisonCost(BrandyMugFarmLocation, iCostNonContestable) + SetGarrisonCost(HlaaluFarmLocation, iCostNonContestable) + SetGarrisonCost(HollyfrostFarmLocation, iCostNonContestable) + SetGarrisonCost(KynesgroveLocation, iCostNonContestable) + SetGarrisonCost(DarkwaterCrossingLocation, iCostNonContestable) + SetGarrisonCost(MixwaterMillLocation, iCostNonContestable) + + SetGarrisonCost(FortAmolLocation, iCostNonContestable) +EndFunction + +Function setInitialGarrisonCostsRift() + SetGarrisonCost(RiftenLocation, iCostNonContestable) + SetGarrisonCost(SnowShodFarmLocation, iCostNonContestable) + ;SetGarrisonCost(GoldenglowFarmLocation, iCostNonContestable) -- GoldenGlowFarm is NOT a normal location. It's quest specific area spawning it's own guards, and should not be part of the Civil War. + SetGarrisonCost(MerryfairFarmLocation, iCostNonContestable) + SetGarrisonCost(IvarsteadLocation, iCostMedium) + SetGarrisonCost(ShorsStoneLocation, iCostSmall) + SetGarrisonCost(HeartwoodMillLocation, iCostSmall) + SetGarrisonCost(SarethiFarmLocation, iCostSmall) + + SetGarrisonCost(FortGreenwallLocation, iCostFort) +EndFunction + +function registerMissionSuccess(Location HoldLocation, bool isFortBattle = False) + CountMissionSuccess += 1 + + log("CWScript", "registerMissionSuccess(HoldLocation:" + HoldLocation + ", isFortBattle:" + isFortBattle + ") CountMissionSuccess = " + CountMissionSuccess + ". Calling DisplayHoldObjective() if isFortBattle == false") + + ;NOTE: + ;If isFortBattle is true, then we should skip displaying the Hold Objective, UNLESS we decide put reimplement the final battles at the capitals + + if isFortBattle == False + DisplayHoldObjective() + EndIf + +EndFunction + +function SetContestedHoldWinType() +{Sets the ContestedHoldWinType variable} + + if ownerContestedHold == ContestedHoldWinner + contestedHoldWinType = 2 ;held onto it + log("CWScript", "SetContestedHoldWinType() set contestedHoldWinType to 2 (defender)") + + Else + contestedHoldWinType = 1 ;took it away from the enemy + log("CWScript", "SetContestedHoldWinType() set contestedHoldWinType to 1 (attacker))") + EndIf + +EndFunction + +Function resolveOffscreen(int CurrentAttackDelta = 0) +{Causes the campaign to resolve offscreen, puts this script in the ResolvingCampaignOffscreen state. When the CWCampaign calls this function, it needs to pass in the CurrentAttackValue. When this parameter is not present, it means we are resolving it in ForcedResolveOffscreen mode.} + + GoToState("ResolvingCampaignOffscreen") + + int winner ;1 = Imperials, 2 = Sons -- these are held in Attacker and Defender + + stopSiegeQuests() ;causes any running siege quest to stop + + if CurrentAttackDelta == 0 ; it means something other than the actual campaign is calling this function, most likely because we are running in a debugging "force offscreen resolution" mode where we aren't really going through all the campaign scripting + CurrentAttackDelta = AttackDelta ;because the campaign isn't calling this function passing in a CurrentAttackDelta, we will use the starting AttackDelta that the CW quest calculated when it picked a hold to contest + + log("CWScript", "resolveOffscreen() called without a CurrentAttackDelta parameter, therefore we are using the initial AttackDelta set by CWScript in StartNewCampaign(): " + CurrentAttackDelta) + + Else + log("CWScript", "resolveOffscreen() called with a CurrentAttackDelta parameter = " + CurrentAttackDelta) + + EndIf + + + ;Always calculate these values for troubleshooting purposes, even if we are going to force the defender to win below + resolutionForced = False + resolutionDieRoll = Utility.RandomInt(0, 100) + resolutionResult = resolutionDieRoll + (CurrentAttackDelta * ResolutionAttackDeltaMultiplier) + If resolutionResult > 50 + contestedHoldWinner = attacker + Else + contestedHoldWinner = defender + EndIf + + ;For major holds with cities, make sure the player involved flag has been set, otherwise force the winner to be the defender (this prevents a major hold changing hands if the player never got in olved) + If (ContestedHold == iReach && playerJoinedCampaginReach == 0) || (ContestedHold == iWhiterun && playerJoinedCampaginWhiterun == 0) || (ContestedHold == iRift && playerJoinedCampaginRift== 0) + contestedHoldWinner = defender + resolutionForced = True + EndIf + + log("CWScript", "resolveOffscreen() resolved with resolutionDieRoll =" + resolutionDieRoll + ", resolutionResult=" + resolutionResult + ", contestedHoldWinner =" + contestedHoldWinner + "(" + FactionName(contestedHoldWinner) + "), resolutionForced =" + resolutionForced + "; Now calling finishCampaign()") + + finishCampaign() + + log("CWScript", "resolveOffscreen() finished. Going to state WaitingToStartNewCampaign") + + GoToState("WaitingToStartNewCampaign") + + +EndFunction + + + diff --git a/source/scripts/cwsiegescript.psc b/source/scripts/cwsiegescript.psc new file mode 100644 index 00000000..1e97289d --- /dev/null +++ b/source/scripts/cwsiegescript.psc @@ -0,0 +1,1596 @@ +Scriptname CWSiegeScript extends Quest Conditional +{Extends Quest} + +;******************* +;This script helps unify the Attack and Defend Quests for attacks and defenses of cities. +;It is essentially a collection of "arrays" of aliases and functions to setup/enable/reset/disable the references in those alisases in those "arrays" + +;"Arrays" holding aliases pointing to soldier references placed in the world +;ImperialAttackerX - these mimic an array called "ImperialAttackerAliases" - (the ones pointing at specific references in the world who have the link refs) +;ImperialDefenderX - these mimic an array called "ImperialDefenderAliases" - (the ones pointing at specific references in the world who have the link refs) +;SonsAttackerX - these mimic an array called "SonsAttackerAliases" - (the ones pointing at specific references in the world who have the link refs) +;SonsDefenderX - these mimic an array called "SonsDefenderAliases" - (the ones pointing at specific references in the world who have the link refs) + +;"Arrays" holding aliases that are used to put packages on the soldiers who are acting as Attackers or Defenders in this instance of the quest (in otherwords which of the above mentioned aliases are actually the attackers and defenders at this very moment) +;AttackerX - these mimic an array called "AttackerAliases" - (the ones with the packages and scripts to make the sieges work) +;DefenderX - these mimic an array called "DefenderAliases" - (the ones with the packages and scripts to make the sieges work) + +;Functions to call from quest stage fragment script: + +;RegisterXYZ() - this is how you pass aliases into the "array" +;DisableXYZ() - this is how you Disable all the references in aliases in the "array" +;EnableXYZ() - this is how you enable all the references in aliases in the "array" +;ResetXYZ() - this is how you Reset all the references in aliases in the "array" +; +;SetUpAliases(bool IsAttackQuest) - sets up, enables, and resets aliases as appropriate to the player faction and attacking Faction (it enables and resets all the generic and attacker/defender aliases, and GenericAttack or GenericDefend as appropriate to the TYPE of QUEST [IsAttackQuest] true = this is an attack on a city, false = this is a defense of a city) +;DisableAllAliases() - disables all the aliases registered into any of the "arrays" (strictly speaking it disables the generic aliases, and the Imperial/SonsAttacker/Defender aliases, not the Attacker/Defender aliases, but the Attacker/Defender aliases are just pointing at a subset of the Imperial/SonsAttacker/Defender aliases, so it amounts to the same thing) + + +;******************* + +CWScript Property CWs Auto + +GlobalVariable Property CWBattlePhase Auto + +GlobalVariable Property CWStateAttackerAtGate Auto +GlobalVariable Property CWStateAttackerBrokeThrough Auto +GlobalVariable Property CWStateAttackerLowReinforcements Auto +GlobalVariable Property CWStateAttackerOutOfReinforcements Auto +GlobalVariable Property CWStateAttackStarted Auto +GlobalVariable Property CWStateDefenderFallingBack Auto +GlobalVariable Property CWStateDefenderLastStand Auto +GlobalVariable Property CWStateDefenderLowReinforcements Auto +GlobalVariable Property CWStateDefenderOutOfReinforcements Auto + +bool Property DoneSettingUpAliases = False auto Hidden +bool Property DoneTurningOnAliases = False auto Hidden + +bool Property WasThisAnAttack Auto hidden +bool DisabledFastTravel = false + +bool Property AttackersHaveWon = false Auto Conditional +bool Property DefendersHaveWon = false Auto Conditional +Int Property CurrentCity Auto Conditional +{Gets set when CWSiege starts: +1 = Solitude +2 = Markarth +4 = Whiterun +8 = Windhelm +9 = Riften +} + +LocationAlias Property City Auto +LocationAlias Property Hold Auto + +;Pointers to references that handle the quest title text replacement +ObjectReference Property TextReplaceDEFENSE Auto +ObjectReference Property TextReplaceATTACK Auto +ReferenceAlias Property ObjAliasTextReplaceAttackDefend Auto + + +;sound control +MusicType Property MUSCombatCivilWar auto +sound Property AMBCombatSoundsLoop Auto +int CombatSoundsLoopInstance + +Weather Property WeatherWhiterun Auto +Weather Property WeatherMarkarth Auto +Weather Property WeatherRiften Auto +Weather Property WeatherSolitude Auto +Weather Property WeatherWindhelm Auto + +Explosion Property CWCatapultExp Auto + + +quest Property DA08 Auto + +Quest Property SolitudeOpening Auto + +Scene Property CWSiegeWhiterunDefendedScene Auto + +Quest Property CWPostWhiterunObj Auto ;objective turned on in stage 200 in CWSiege quest, and completed in CWSiegeJarlThankYouTopic fragment in CW quest + +MS11QuestScript Property MS11 Auto ;ised tp call a function on MS11 to help handle murder scene not occuring duing siege + +; ## External Aliases ## +Quest Property CWSiegeObj Auto +LocationAlias Property CWSiegeObjCity Auto +ReferenceAlias Property CWSiegeObjCityGate Auto +ReferenceAlias Property CWSiegeObjJarl Auto +ReferenceAlias Property CWSiegeObjGeneral Auto + +ReferenceAlias Property CWSiegeObjObjective1A Auto +ReferenceAlias Property CWSiegeObjObjective2A Auto +ReferenceAlias Property CWSiegeObjObjective3A Auto +ReferenceAlias Property CWSiegeObjObjective4A Auto + +ReferenceAlias Property CWSiegeObjObjective1B Auto +ReferenceAlias Property CWSiegeObjObjective2B Auto +ReferenceAlias Property CWSiegeObjObjective3B Auto +ReferenceAlias Property CWSiegeObjObjective4B Auto + +ReferenceAlias Property CWReservationsBalgruuf Auto +ReferenceAlias Property CWReservationsProventus Auto +ReferenceAlias Property CWReservationsIrileth Auto + +;"Array" of aliases +;rather than declaring these again on all siege scripts, we will create a function that the quest fragment can pass in the Alias_XXX aliases and put them in the "array" + +;Imperial Attacker/Defender aliases (the ones pointing at specific references in the world who have the link refs) +ReferenceAlias ImperialAttacker1 +ReferenceAlias ImperialAttacker2 +ReferenceAlias ImperialAttacker3 +ReferenceAlias ImperialAttacker4 +ReferenceAlias ImperialAttacker5 +ReferenceAlias ImperialAttacker6 +ReferenceAlias ImperialAttacker7 +ReferenceAlias ImperialAttacker8 +ReferenceAlias ImperialAttacker9 +ReferenceAlias ImperialAttacker10 + +ReferenceAlias ImperialDefender1 +ReferenceAlias ImperialDefender2 +ReferenceAlias ImperialDefender3 +ReferenceAlias ImperialDefender4 +ReferenceAlias ImperialDefender5 +ReferenceAlias ImperialDefender6 +ReferenceAlias ImperialDefender7 +ReferenceAlias ImperialDefender8 +ReferenceAlias ImperialDefender9 +ReferenceAlias ImperialDefender10 + +;Sons Attacker/Defender aliases (the ones pointing at specific references in the world who have the link refs) +ReferenceAlias SonsAttacker1 +ReferenceAlias SonsAttacker2 +ReferenceAlias SonsAttacker3 +ReferenceAlias SonsAttacker4 +ReferenceAlias SonsAttacker5 +ReferenceAlias SonsAttacker6 +ReferenceAlias SonsAttacker7 +ReferenceAlias SonsAttacker8 +ReferenceAlias SonsAttacker9 +ReferenceAlias SonsAttacker10 + +ReferenceAlias SonsDefender1 +ReferenceAlias SonsDefender2 +ReferenceAlias SonsDefender3 +ReferenceAlias SonsDefender4 +ReferenceAlias SonsDefender5 +ReferenceAlias SonsDefender6 +ReferenceAlias SonsDefender7 +ReferenceAlias SonsDefender8 +ReferenceAlias SonsDefender9 +ReferenceAlias SonsDefender10 + +;Attacker/Defender Aliases (the ones with the packages and scripts to make the sieges work, the above aliases will be shoved into these depending on who is attacking/defending) +ReferenceAlias Attacker1 +ReferenceAlias Attacker2 +ReferenceAlias Attacker3 +ReferenceAlias Attacker4 +ReferenceAlias Attacker5 +ReferenceAlias Attacker6 +ReferenceAlias Attacker7 +ReferenceAlias Attacker8 +ReferenceAlias Attacker9 +ReferenceAlias Attacker10 + +ReferenceAlias Defender1 +ReferenceAlias Defender2 +ReferenceAlias Defender3 +ReferenceAlias Defender4 +ReferenceAlias Defender5 +ReferenceAlias Defender6 +ReferenceAlias Defender7 +ReferenceAlias Defender8 +ReferenceAlias Defender9 +ReferenceAlias Defender10 + + +;Generic "array" of aliases of things we want to enable/reset/disable as a group (things like fires, catapolts, barricades, etc.) +ReferenceAlias Generic1 +ReferenceAlias Generic2 +ReferenceAlias Generic3 +ReferenceAlias Generic4 +ReferenceAlias Generic5 +ReferenceAlias Generic6 +ReferenceAlias Generic7 +ReferenceAlias Generic8 +ReferenceAlias Generic9 +ReferenceAlias Generic10 +ReferenceAlias Generic11 +ReferenceAlias Generic12 +ReferenceAlias Generic13 +ReferenceAlias Generic14 +ReferenceAlias Generic15 +ReferenceAlias Generic16 +ReferenceAlias Generic17 +ReferenceAlias Generic18 +ReferenceAlias Generic19 +ReferenceAlias Generic20 +ReferenceAlias Generic21 +ReferenceAlias Generic22 +ReferenceAlias Generic23 +ReferenceAlias Generic24 +ReferenceAlias Generic25 +ReferenceAlias Generic26 +ReferenceAlias Generic27 +ReferenceAlias Generic28 +ReferenceAlias Generic29 +ReferenceAlias Generic30 + + +;For ATTACK quests -Generic "array" of aliases of things we want to enable/reset/disable as a group (things like fires, catapolts, barricades, etc.) +ReferenceAlias GenericAttack1 +ReferenceAlias GenericAttack2 +ReferenceAlias GenericAttack3 +ReferenceAlias GenericAttack4 +ReferenceAlias GenericAttack5 +ReferenceAlias GenericAttack6 +ReferenceAlias GenericAttack7 +ReferenceAlias GenericAttack8 +ReferenceAlias GenericAttack9 +ReferenceAlias GenericAttack10 +ReferenceAlias GenericAttack11 +ReferenceAlias GenericAttack12 +ReferenceAlias GenericAttack13 +ReferenceAlias GenericAttack14 +ReferenceAlias GenericAttack15 +ReferenceAlias GenericAttack16 +ReferenceAlias GenericAttack17 +ReferenceAlias GenericAttack18 +ReferenceAlias GenericAttack19 +ReferenceAlias GenericAttack20 +ReferenceAlias GenericAttack21 +ReferenceAlias GenericAttack22 +ReferenceAlias GenericAttack23 +ReferenceAlias GenericAttack24 +ReferenceAlias GenericAttack25 +ReferenceAlias GenericAttack26 +ReferenceAlias GenericAttack27 +ReferenceAlias GenericAttack28 +ReferenceAlias GenericAttack29 +ReferenceAlias GenericAttack30 + +;For DEFEND quests -Generic "array" of aliases of things we want to enable/reset/disable as a group (things like fires, catapolts, barricades, etc.) +ReferenceAlias GenericDefend1 +ReferenceAlias GenericDefend2 +ReferenceAlias GenericDefend3 +ReferenceAlias GenericDefend4 +ReferenceAlias GenericDefend5 +ReferenceAlias GenericDefend6 +ReferenceAlias GenericDefend7 +ReferenceAlias GenericDefend8 +ReferenceAlias GenericDefend9 +ReferenceAlias GenericDefend10 +ReferenceAlias GenericDefend11 +ReferenceAlias GenericDefend12 +ReferenceAlias GenericDefend13 +ReferenceAlias GenericDefend14 +ReferenceAlias GenericDefend15 +ReferenceAlias GenericDefend16 +ReferenceAlias GenericDefend17 +ReferenceAlias GenericDefend18 +ReferenceAlias GenericDefend19 +ReferenceAlias GenericDefend20 +ReferenceAlias GenericDefend21 +ReferenceAlias GenericDefend22 +ReferenceAlias GenericDefend23 +ReferenceAlias GenericDefend24 +ReferenceAlias GenericDefend25 +ReferenceAlias GenericDefend26 +ReferenceAlias GenericDefend27 +ReferenceAlias GenericDefend28 +ReferenceAlias GenericDefend29 +ReferenceAlias GenericDefend30 + + +ReferenceAlias AttackerSonsCampMapMarker +Referencealias AttackerImperialCampMapMarker +ReferenceAlias MapMarkerToDisable1 +ReferenceAlias MapMarkerToDisable2 +ReferenceAlias MapMarkerToDisable3 +ReferenceAlias MapMarkerToDisable4 +ReferenceAlias MapMarkerToDisable5 +ReferenceAlias MapMarkerToDisable6 +ReferenceAlias MapMarkerToDisable7 +ReferenceAlias MapMarkerToDisable8 +ReferenceAlias MapMarkerToDisable9 +ReferenceAlias MapMarkerToDisable10 +ReferenceAlias MapMarkerToDisable11 +ReferenceAlias MapMarkerToDisable12 +ReferenceAlias MapMarkerToDisable13 +ReferenceAlias MapMarkerToDisable14 +ReferenceAlias MapMarkerToDisable15 +ReferenceAlias MapMarkerToDisable16 + +function RegisterMapMarkerAliases(ReferenceAlias AttackerSonsCampMapMarkerAlias, ReferenceAlias AttackerImperialCampMapMarkerAlias, \ +ReferenceAlias MapMarkerToDisable1Alias, \ +ReferenceAlias MapMarkerToDisable2Alias, \ +ReferenceAlias MapMarkerToDisable3Alias, \ +ReferenceAlias MapMarkerToDisable4Alias, \ +ReferenceAlias MapMarkerToDisable5Alias, \ +ReferenceAlias MapMarkerToDisable6Alias, \ +ReferenceAlias MapMarkerToDisable7Alias, \ +ReferenceAlias MapMarkerToDisable8Alias, \ +ReferenceAlias MapMarkerToDisable9Alias, \ +ReferenceAlias MapMarkerToDisable10Alias, \ +ReferenceAlias MapMarkerToDisable11Alias, \ +ReferenceAlias MapMarkerToDisable12Alias, \ +ReferenceAlias MapMarkerToDisable13Alias, \ +ReferenceAlias MapMarkerToDisable14Alias, \ +ReferenceAlias MapMarkerToDisable15Alias, \ +ReferenceAlias MapMarkerToDisable16Alias) + + AttackerSonsCampMapMarker = AttackerSonsCampMapMarkerAlias + AttackerImperialCampMapMarker = AttackerImperialCampMapMarkerAlias + MapMarkerToDisable1 = MapMarkerToDisable1Alias + MapMarkerToDisable2 = MapMarkerToDisable2Alias + MapMarkerToDisable3 = MapMarkerToDisable3Alias + MapMarkerToDisable4 = MapMarkerToDisable4Alias + MapMarkerToDisable5 = MapMarkerToDisable5Alias + MapMarkerToDisable6 = MapMarkerToDisable6Alias + MapMarkerToDisable7 = MapMarkerToDisable7Alias + MapMarkerToDisable8 = MapMarkerToDisable8Alias + MapMarkerToDisable9 = MapMarkerToDisable9Alias + MapMarkerToDisable10 = MapMarkerToDisable10Alias + MapMarkerToDisable11 = MapMarkerToDisable11Alias + MapMarkerToDisable12 = MapMarkerToDisable12Alias + MapMarkerToDisable13 = MapMarkerToDisable13Alias + MapMarkerToDisable14 = MapMarkerToDisable14Alias + MapMarkerToDisable15 = MapMarkerToDisable15Alias + MapMarkerToDisable16 = MapMarkerToDisable16Alias + +EndFunction + +function ToggleMapMarkersAndFastTravelStartBattle(bool isAttackQuest) + +; CWScript.Log("CWSiegeScript", self + "ToggleMapMarkersAndFastTravelStartBattle()") + + isAttackQuest = WasThisAnAttack ;added this late in the game (set in stage 0), easier to just do this than fix all instances that call this function and pass in a param + + + DisabledFastTravel = false ;clear it to be on the safe side + + if isAttackQuest + + if CWs.PlayerAllegiance == 1 + AttackerImperialCampMapMarker.TryToEnable() + elseif CWs.PlayerAllegiance == 2 + AttackerSonsCampMapMarker.TryToEnable() + endif + MapMarkerToDisable1.TryToDisable() + MapMarkerToDisable2.TryToDisable() + MapMarkerToDisable3.TryToDisable() + MapMarkerToDisable4.TryToDisable() + MapMarkerToDisable5.TryToDisable() + MapMarkerToDisable6.TryToDisable() + MapMarkerToDisable7.TryToDisable() + MapMarkerToDisable8.TryToDisable() + MapMarkerToDisable9.TryToDisable() + MapMarkerToDisable10.TryToDisable() + MapMarkerToDisable11.TryToDisable() + MapMarkerToDisable12.TryToDisable() + MapMarkerToDisable13.TryToDisable() + MapMarkerToDisable14.TryToDisable() + MapMarkerToDisable15.TryToDisable() + MapMarkerToDisable16.TryToDisable() + + Else +; CWScript.Log("CWSiegeScript", self + "DISABLING FAST TRAVEL!", 1, true, True) + Game.EnableFastTravel(false) + DisabledFastTravel = true + + + + EndIf + +EndFunction + +function ToggleMapMarkersAndFastTravelEndBattle(bool isAttackQuest) + +; CWScript.Log("CWSiegeScript", self + "ToggleMapMarkersAndFastTravelEndBattle()") + + isAttackQuest = WasThisAnAttack ;added this late in the game (set in stage 0), easier to just do this than fix all instances that call this function and pass in a param + + if isAttackQuest + + AttackerImperialCampMapMarker.TryToDisable() + AttackerSonsCampMapMarker.TryToDisable() + + MapMarkerToDisable1.TryToEnable() + MapMarkerToDisable2.TryToEnable() + MapMarkerToDisable3.TryToEnable() + MapMarkerToDisable4.TryToEnable() + MapMarkerToDisable5.TryToEnable() + MapMarkerToDisable6.TryToEnable() + MapMarkerToDisable7.TryToEnable() + MapMarkerToDisable8.TryToEnable() + MapMarkerToDisable9.TryToEnable() + MapMarkerToDisable10.TryToEnable() + MapMarkerToDisable11.TryToEnable() + MapMarkerToDisable12.TryToEnable() + MapMarkerToDisable13.TryToEnable() + MapMarkerToDisable14.TryToEnable() + MapMarkerToDisable15.TryToEnable() + MapMarkerToDisable16.TryToEnable() + + Else + + if DisabledFastTravel == true ;reminder why I am checking this: I need to check to make sure this quest actually disabled fast travel before turning it on again, because this might start/fail offscreen and I need to make sure I don't enable fast travel if the player didn't get involved +; CWScript.Log("CWSiegeScript", self + "ENABLING FAST TRAVEL!", 1, true, True) + Game.EnableFastTravel(true) + DisabledFastTravel = False + + + endif + + EndIf + +EndFunction + + +;Register functions essentially shove the aliases from the quest into arrays to be used more conveniently by other function calls + +;Register Imperial aliases +Function RegisterImperialAttackerAliases(ReferenceAlias RefAlias1, ReferenceAlias RefAlias2, ReferenceAlias RefAlias3, ReferenceAlias RefAlias4, ReferenceAlias RefAlias5, ReferenceAlias RefAlias6, ReferenceAlias RefAlias7, ReferenceAlias RefAlias8, ReferenceAlias RefAlias9, ReferenceAlias RefAlias10 ) +; CWScript.Log("CWSiegeScript", self + "calling RegisterImperialAttackerAliases()" + RefAlias1 + "," + RefAlias2 + "," + RefAlias3 + "," + RefAlias4 + "," + RefAlias5 + "," + RefAlias6 + "," + RefAlias7 + "," + RefAlias8 + "," + RefAlias9 + "," + RefAlias10 ) + ImperialAttacker1 = RefAlias1 + ImperialAttacker2 = RefAlias2 + ImperialAttacker3 = RefAlias3 + ImperialAttacker4 = RefAlias4 + ImperialAttacker5 = RefAlias5 + ImperialAttacker6 = RefAlias6 + ImperialAttacker7 = RefAlias7 + ImperialAttacker8 = RefAlias8 + ImperialAttacker9 = RefAlias9 + ImperialAttacker10 = RefAlias10 + +EndFunction + +Function RegisterImperialDefenderAliases(ReferenceAlias RefAlias1, ReferenceAlias RefAlias2, ReferenceAlias RefAlias3, ReferenceAlias RefAlias4, ReferenceAlias RefAlias5, ReferenceAlias RefAlias6, ReferenceAlias RefAlias7, ReferenceAlias RefAlias8, ReferenceAlias RefAlias9, ReferenceAlias RefAlias10 ) +; CWScript.Log("CWSiegeScript", self + "calling RegisterImperialDefenderAliases()" + RefAlias1 + "," + RefAlias2 + "," + RefAlias3 + "," + RefAlias4 + "," + RefAlias5 + "," + RefAlias6 + "," + RefAlias7 + "," + RefAlias8 + "," + RefAlias9 + "," + RefAlias10 ) + ImperialDefender1 = RefAlias1 + ImperialDefender2 = RefAlias2 + ImperialDefender3 = RefAlias3 + ImperialDefender4 = RefAlias4 + ImperialDefender5 = RefAlias5 + ImperialDefender6 = RefAlias6 + ImperialDefender7 = RefAlias7 + ImperialDefender8 = RefAlias8 + ImperialDefender9 = RefAlias9 + ImperialDefender10 = RefAlias10 + +EndFunction + +;Register Sons aliases +Function RegisterSonsAttackerAliases(ReferenceAlias RefAlias1, ReferenceAlias RefAlias2, ReferenceAlias RefAlias3, ReferenceAlias RefAlias4, ReferenceAlias RefAlias5, ReferenceAlias RefAlias6, ReferenceAlias RefAlias7, ReferenceAlias RefAlias8, ReferenceAlias RefAlias9, ReferenceAlias RefAlias10 ) +; CWScript.Log("CWSiegeScript", self + "calling RegisterSonsAttackerAliases()" + RefAlias1 + "," + RefAlias2 + "," + RefAlias3 + "," + RefAlias4 + "," + RefAlias5 + "," + RefAlias6 + "," + RefAlias7 + "," + RefAlias8 + "," + RefAlias9 + "," + RefAlias10 ) + SonsAttacker1 = RefAlias1 + SonsAttacker2 = RefAlias2 + SonsAttacker3 = RefAlias3 + SonsAttacker4 = RefAlias4 + SonsAttacker5 = RefAlias5 + SonsAttacker6 = RefAlias6 + SonsAttacker7 = RefAlias7 + SonsAttacker8 = RefAlias8 + SonsAttacker9 = RefAlias9 + SonsAttacker10 = RefAlias10 + +EndFunction + +Function RegisterSonsDefenderAliases(ReferenceAlias RefAlias1, ReferenceAlias RefAlias2, ReferenceAlias RefAlias3, ReferenceAlias RefAlias4, ReferenceAlias RefAlias5, ReferenceAlias RefAlias6, ReferenceAlias RefAlias7, ReferenceAlias RefAlias8, ReferenceAlias RefAlias9, ReferenceAlias RefAlias10 ) +; CWScript.Log("CWSiegeScript", self + "calling RegisterSonsDefenderAliases()" + RefAlias1 + "," + RefAlias2 + "," + RefAlias3 + "," + RefAlias4 + "," + RefAlias5 + "," + RefAlias6 + "," + RefAlias7 + "," + RefAlias8 + "," + RefAlias9 + "," + RefAlias10 ) + SonsDefender1 = RefAlias1 + SonsDefender2 = RefAlias2 + SonsDefender3 = RefAlias3 + SonsDefender4 = RefAlias4 + SonsDefender5 = RefAlias5 + SonsDefender6 = RefAlias6 + SonsDefender7 = RefAlias7 + SonsDefender8 = RefAlias8 + SonsDefender9 = RefAlias9 + SonsDefender10 = RefAlias10 + +EndFunction + +;Register Attacker Aliases +Function RegisterAttackerAliases(ReferenceAlias RefAlias1, ReferenceAlias RefAlias2, ReferenceAlias RefAlias3, ReferenceAlias RefAlias4, ReferenceAlias RefAlias5, ReferenceAlias RefAlias6, ReferenceAlias RefAlias7, ReferenceAlias RefAlias8, ReferenceAlias RefAlias9, ReferenceAlias RefAlias10 ) +; CWScript.Log("CWSiegeScript", self + "calling RegisterAttackerAliases()" + RefAlias1 + "," + RefAlias2 + "," + RefAlias3 + "," + RefAlias4 + "," + RefAlias5 + "," + RefAlias6 + "," + RefAlias7 + "," + RefAlias8 + "," + RefAlias9 + "," + RefAlias10 ) + Attacker1 = RefAlias1 + Attacker2 = RefAlias2 + Attacker3 = RefAlias3 + Attacker4 = RefAlias4 + Attacker5 = RefAlias5 + Attacker6 = RefAlias6 + Attacker7 = RefAlias7 + Attacker8 = RefAlias8 + Attacker9 = RefAlias9 + Attacker10 = RefAlias10 + +EndFunction + +;Register Defender Aliases +Function RegisterDefenderAliases(ReferenceAlias RefAlias1, ReferenceAlias RefAlias2, ReferenceAlias RefAlias3, ReferenceAlias RefAlias4, ReferenceAlias RefAlias5, ReferenceAlias RefAlias6, ReferenceAlias RefAlias7, ReferenceAlias RefAlias8, ReferenceAlias RefAlias9, ReferenceAlias RefAlias10 ) +; CWScript.Log("CWSiegeScript", self + "calling RegisterDefenderAliases()" + RefAlias1 + "," + RefAlias2 + "," + RefAlias3 + "," + RefAlias4 + "," + RefAlias5 + "," + RefAlias6 + "," + RefAlias7 + "," + RefAlias8 + "," + RefAlias9 + "," + RefAlias10 ) + Defender1 = RefAlias1 + Defender2 = RefAlias2 + Defender3 = RefAlias3 + Defender4 = RefAlias4 + Defender5 = RefAlias5 + Defender6 = RefAlias6 + Defender7 = RefAlias7 + Defender8 = RefAlias8 + Defender9 = RefAlias9 + Defender10 = RefAlias10 + +EndFunction + +;Register Generic Aliases +Function RegisterGenericAliases( \ +ReferenceAlias RefAlias1, ReferenceAlias RefAlias2 = None, ReferenceAlias RefAlias3 = None, ReferenceAlias RefAlias4 = None, ReferenceAlias RefAlias5 = None, ReferenceAlias RefAlias6 = None, ReferenceAlias RefAlias7 = None, ReferenceAlias RefAlias8 = None, ReferenceAlias RefAlias9 = None, ReferenceAlias RefAlias10 = None, \ +ReferenceAlias RefAlias11 = None, ReferenceAlias RefAlias12 = None, ReferenceAlias RefAlias13 = None, ReferenceAlias RefAlias14 = None, ReferenceAlias RefAlias15 = None, ReferenceAlias RefAlias16 = None, ReferenceAlias RefAlias17 = None, ReferenceAlias RefAlias18 = None, ReferenceAlias RefAlias19 = None, ReferenceAlias RefAlias20 = None, \ +ReferenceAlias RefAlias21 = None, ReferenceAlias RefAlias22 = None, ReferenceAlias RefAlias23 = None, ReferenceAlias RefAlias24 = None, ReferenceAlias RefAlias25 = None, ReferenceAlias RefAlias26 = None, ReferenceAlias RefAlias27 = None, ReferenceAlias RefAlias28 = None, ReferenceAlias RefAlias29 = None, ReferenceAlias RefAlias30 = None \ +) +; CWScript.Log("CWSiegeScript", self + "calling RegisterGenericAliases()" + \ +; RefAlias1 + "," + RefAlias2 + "," + RefAlias3 + "," + RefAlias4 + "," + RefAlias5 + "," + RefAlias6 + "," + RefAlias7 + "," + RefAlias8 + "," + RefAlias9 + "," + RefAlias10 + "," + \ +; RefAlias11 + "," + RefAlias12 + "," + RefAlias13 + "," + RefAlias14 + "," + RefAlias15 + "," + RefAlias16 + "," + RefAlias17 + "," + RefAlias18 + "," + RefAlias19 + "," + RefAlias20 + "," + \ +; RefAlias21 + "," + RefAlias22 + "," + RefAlias23 + "," + RefAlias24 + "," + RefAlias25 + "," + RefAlias26 + "," + RefAlias27 + "," + RefAlias28 + "," + RefAlias29 + "," + RefAlias30 + "," \ +; ) + + Generic1 = RefAlias1 + Generic2 = RefAlias2 + Generic3 = RefAlias3 + Generic4 = RefAlias4 + Generic5 = RefAlias5 + Generic6 = RefAlias6 + Generic7 = RefAlias7 + Generic8 = RefAlias8 + Generic9 = RefAlias9 + Generic10 = RefAlias10 + + Generic11 = RefAlias11 + Generic12 = RefAlias12 + Generic13 = RefAlias13 + Generic14 = RefAlias14 + Generic15 = RefAlias15 + Generic16 = RefAlias16 + Generic17 = RefAlias17 + Generic18 = RefAlias18 + Generic19 = RefAlias19 + Generic20 = RefAlias20 + + Generic21 = RefAlias21 + Generic22 = RefAlias22 + Generic23 = RefAlias23 + Generic24 = RefAlias24 + Generic25 = RefAlias25 + Generic26 = RefAlias26 + Generic27 = RefAlias27 + Generic28 = RefAlias28 + Generic29 = RefAlias29 + Generic30 = RefAlias30 + + +EndFunction + +;Register GenericAttack Aliases +Function RegisterGenericAttackAliases( \ +ReferenceAlias RefAlias1, ReferenceAlias RefAlias2 = None, ReferenceAlias RefAlias3 = None, ReferenceAlias RefAlias4 = None, ReferenceAlias RefAlias5 = None, ReferenceAlias RefAlias6 = None, ReferenceAlias RefAlias7 = None, ReferenceAlias RefAlias8 = None, ReferenceAlias RefAlias9 = None, ReferenceAlias RefAlias10 = None, \ +ReferenceAlias RefAlias11 = None, ReferenceAlias RefAlias12 = None, ReferenceAlias RefAlias13 = None, ReferenceAlias RefAlias14 = None, ReferenceAlias RefAlias15 = None, ReferenceAlias RefAlias16 = None, ReferenceAlias RefAlias17 = None, ReferenceAlias RefAlias18 = None, ReferenceAlias RefAlias19 = None, ReferenceAlias RefAlias20 = None, \ +ReferenceAlias RefAlias21 = None, ReferenceAlias RefAlias22 = None, ReferenceAlias RefAlias23 = None, ReferenceAlias RefAlias24 = None, ReferenceAlias RefAlias25 = None, ReferenceAlias RefAlias26 = None, ReferenceAlias RefAlias27 = None, ReferenceAlias RefAlias28 = None, ReferenceAlias RefAlias29 = None, ReferenceAlias RefAlias30 = None \ +) +; CWScript.Log("CWSiegeScript", self + "calling RegisterGenericAttackAliases()" + \ +; RefAlias1 + "," + RefAlias2 + "," + RefAlias3 + "," + RefAlias4 + "," + RefAlias5 + "," + RefAlias6 + "," + RefAlias7 + "," + RefAlias8 + "," + RefAlias9 + "," + RefAlias10 + "," + \ +; RefAlias11 + "," + RefAlias12 + "," + RefAlias13 + "," + RefAlias14 + "," + RefAlias15 + "," + RefAlias16 + "," + RefAlias17 + "," + RefAlias18 + "," + RefAlias19 + "," + RefAlias20 + "," + \ +; RefAlias21 + "," + RefAlias22 + "," + RefAlias23 + "," + RefAlias24 + "," + RefAlias25 + "," + RefAlias26 + "," + RefAlias27 + "," + RefAlias28 + "," + RefAlias29 + "," + RefAlias30 + "," \ +; ) + + GenericAttack1 = RefAlias1 + GenericAttack2 = RefAlias2 + GenericAttack3 = RefAlias3 + GenericAttack4 = RefAlias4 + GenericAttack5 = RefAlias5 + GenericAttack6 = RefAlias6 + GenericAttack7 = RefAlias7 + GenericAttack8 = RefAlias8 + GenericAttack9 = RefAlias9 + GenericAttack10 = RefAlias10 + + GenericAttack11 = RefAlias11 + GenericAttack12 = RefAlias12 + GenericAttack13 = RefAlias13 + GenericAttack14 = RefAlias14 + GenericAttack15 = RefAlias15 + GenericAttack16 = RefAlias16 + GenericAttack17 = RefAlias17 + GenericAttack18 = RefAlias18 + GenericAttack19 = RefAlias19 + GenericAttack20 = RefAlias20 + + GenericAttack21 = RefAlias21 + GenericAttack22 = RefAlias22 + GenericAttack23 = RefAlias23 + GenericAttack24 = RefAlias24 + GenericAttack25 = RefAlias25 + GenericAttack26 = RefAlias26 + GenericAttack27 = RefAlias27 + GenericAttack28 = RefAlias28 + GenericAttack29 = RefAlias29 + GenericAttack30 = RefAlias30 + +EndFunction + +;Register GenericDefend Aliases +Function RegisterGenericDefendAliases( \ +ReferenceAlias RefAlias1, ReferenceAlias RefAlias2 = None, ReferenceAlias RefAlias3 = None, ReferenceAlias RefAlias4 = None, ReferenceAlias RefAlias5 = None, ReferenceAlias RefAlias6 = None, ReferenceAlias RefAlias7 = None, ReferenceAlias RefAlias8 = None, ReferenceAlias RefAlias9 = None, ReferenceAlias RefAlias10 = None, \ +ReferenceAlias RefAlias11 = None, ReferenceAlias RefAlias12 = None, ReferenceAlias RefAlias13 = None, ReferenceAlias RefAlias14 = None, ReferenceAlias RefAlias15 = None, ReferenceAlias RefAlias16 = None, ReferenceAlias RefAlias17 = None, ReferenceAlias RefAlias18 = None, ReferenceAlias RefAlias19 = None, ReferenceAlias RefAlias20 = None, \ +ReferenceAlias RefAlias21 = None, ReferenceAlias RefAlias22 = None, ReferenceAlias RefAlias23 = None, ReferenceAlias RefAlias24 = None, ReferenceAlias RefAlias25 = None, ReferenceAlias RefAlias26 = None, ReferenceAlias RefAlias27 = None, ReferenceAlias RefAlias28 = None, ReferenceAlias RefAlias29 = None, ReferenceAlias RefAlias30 = None \ +) +; CWScript.Log("CWSiegeScript", self + "calling RegisterGenericDefendAliases()" + \ +; RefAlias1 + "," + RefAlias2 + "," + RefAlias3 + "," + RefAlias4 + "," + RefAlias5 + "," + RefAlias6 + "," + RefAlias7 + "," + RefAlias8 + "," + RefAlias9 + "," + RefAlias10 + "," + \ +; RefAlias11 + "," + RefAlias12 + "," + RefAlias13 + "," + RefAlias14 + "," + RefAlias15 + "," + RefAlias16 + "," + RefAlias17 + "," + RefAlias18 + "," + RefAlias19 + "," + RefAlias20 + "," + \ +; RefAlias21 + "," + RefAlias22 + "," + RefAlias23 + "," + RefAlias24 + "," + RefAlias25 + "," + RefAlias26 + "," + RefAlias27 + "," + RefAlias28 + "," + RefAlias29 + "," + RefAlias30 + "," \ +; ) + + GenericDefend1 = RefAlias1 + GenericDefend2 = RefAlias2 + GenericDefend3 = RefAlias3 + GenericDefend4 = RefAlias4 + GenericDefend5 = RefAlias5 + GenericDefend6 = RefAlias6 + GenericDefend7 = RefAlias7 + GenericDefend8 = RefAlias8 + GenericDefend9 = RefAlias9 + GenericDefend10 = RefAlias10 + + GenericDefend11 = RefAlias11 + GenericDefend12 = RefAlias12 + GenericDefend13 = RefAlias13 + GenericDefend14 = RefAlias14 + GenericDefend15 = RefAlias15 + GenericDefend16 = RefAlias16 + GenericDefend17 = RefAlias17 + GenericDefend18 = RefAlias18 + GenericDefend19 = RefAlias19 + GenericDefend20 = RefAlias20 + + GenericDefend21 = RefAlias21 + GenericDefend22 = RefAlias22 + GenericDefend23 = RefAlias23 + GenericDefend24 = RefAlias24 + GenericDefend25 = RefAlias25 + GenericDefend26 = RefAlias26 + GenericDefend27 = RefAlias27 + GenericDefend28 = RefAlias28 + GenericDefend29 = RefAlias29 + GenericDefend30 = RefAlias30 + +EndFunction + +Function RegisterAliasesWithCWReinforcementScript(Location SiegeLocationAttackPoint) +; CWScript.Log("CWSiegeScript", self + "calling RegisterAliasesWithCWReinforcementScript()") + + CWReinforcementControllerScript CWReinforcementControllerS = (self as quest ) as CWReinforcementControllerScript + + CWReinforcementControllerS.RegisterAttackPoint(SiegeLocationAttackPoint) + + CWReinforcementControllerS.RegisterAlias(Attacker1) + CWReinforcementControllerS.RegisterAlias(Attacker2) + CWReinforcementControllerS.RegisterAlias(Attacker3) + CWReinforcementControllerS.RegisterAlias(Attacker4) + CWReinforcementControllerS.RegisterAlias(Attacker5) + CWReinforcementControllerS.RegisterAlias(Attacker6) + CWReinforcementControllerS.RegisterAlias(Attacker7) + CWReinforcementControllerS.RegisterAlias(Attacker8) + CWReinforcementControllerS.RegisterAlias(Attacker9) + CWReinforcementControllerS.RegisterAlias(Attacker10) + + CWReinforcementControllerS.RegisterAlias(Defender1) + CWReinforcementControllerS.RegisterAlias(Defender2) + CWReinforcementControllerS.RegisterAlias(Defender3) + CWReinforcementControllerS.RegisterAlias(Defender4) + CWReinforcementControllerS.RegisterAlias(Defender5) + CWReinforcementControllerS.RegisterAlias(Defender6) + CWReinforcementControllerS.RegisterAlias(Defender7) + CWReinforcementControllerS.RegisterAlias(Defender8) + CWReinforcementControllerS.RegisterAlias(Defender9) + CWReinforcementControllerS.RegisterAlias(Defender10) + +EndFunction + +Function RegisterSpawnAttackerAliasesWithCWReinforcementScript(ReferenceAlias Marker1Alias, ReferenceAlias Marker2Alias, ReferenceAlias Marker3Alias, ReferenceAlias Marker4Alias, ReferenceAlias FailSafeMarkerAlias) + CWReinforcementControllerScript CWReinforcementControllerS = (self as quest ) as CWReinforcementControllerScript + +; CWScript.Log("CWSiegeScript", self + "RegisterSpawnAttackerAliasesWithCWReinforcementScript() calling RegisterSpawnAttackerAliases() on CWReinforcementControllerScript") + CWReinforcementControllerS.RegisterSpawnAttackerAliases(Marker1Alias, Marker2Alias, Marker3Alias, Marker4Alias, FailSafeMarkerAlias) + +EndFunction + +Function RegisterSpawnDefenderAliasesWithCWReinforcementScript(ReferenceAlias Marker1Alias, ReferenceAlias Marker2Alias, ReferenceAlias Marker3Alias, ReferenceAlias Marker4Alias, ReferenceAlias FailSafeMarkerAlias) + CWReinforcementControllerScript CWReinforcementControllerS = (self as quest ) as CWReinforcementControllerScript + +; CWScript.Log("CWSiegeScript", self + "RegisterSpawnDefenderAliasesWithCWReinforcementScript() calling RegisterSpawnDefenderAliases() on CWReinforcementControllerScript") + CWReinforcementControllerS.RegisterSpawnDefenderAliases(Marker1Alias, Marker2Alias, Marker3Alias, Marker4Alias, FailSafeMarkerAlias) + +EndFunction + +Function SetInfinitePoolsOnCWReinforcementScript() + CWReinforcementControllerScript CWReinforcementControllerS = (self as quest ) as CWReinforcementControllerScript + +; CWScript.Log("CWSiegeScript", self + "setInfinitePoolsOnCWReinforcementScript() calling SetInfinitePools() on CWReinforcementControllerScript") + CWReinforcementControllerS.SetInfinitePools() +EndFunction + + +Function SetPoolAttackerOnCWReinforcementScript(int BasePool, float AttackDeltaMult = 1.0, float scaleMult = 1.0, bool InfinitePool = False) + CWReinforcementControllerScript CWReinforcementControllerS = (self as quest ) as CWReinforcementControllerScript + +; CWScript.Log("CWSiegeScript", self + "SetPoolAttackerOnCWReinforcementScript() calling SetPoolAttacker() on CWReinforcementControllerScript") + CWReinforcementControllerS.SetPoolAttacker(BasePool, AttackDeltaMult, scaleMult, InfinitePool ) +EndFunction + +Function SetPoolDefenderOnCWReinforcementScript(int BasePool, float AttackDeltaMult = 1.0, float scaleMult = 1.0, bool InfinitePool = False) + CWReinforcementControllerScript CWReinforcementControllerS = (self as quest ) as CWReinforcementControllerScript + +; CWScript.Log("CWSiegeScript", self + "SetPoolDefenderOnCWReinforcementScript() calling SetPoolDefender() on CWReinforcementControllerScript") + CWReinforcementControllerS.SetPoolDefender(BasePool, AttackDeltaMult, scaleMult, InfinitePool ) +EndFunction + + +function DisableAllAliases() +; CWScript.Log("CWSiegeScript", self + "calling DisableAllAliases()") + DisableImperialSonsAliases() + DisableGenericAliases() + DisableGenericAttackAliases() + DisableGenericDefendAliases() + +EndFunction + +Function SetUpAliases(Location LocationOfSiege) + DoneSettingUpAliases = false + +; CWScript.Log("CWSiegeScript", self + "calling SetUpAliases()") + + DisableImperialSonsAliases() ;disables ALL the soldiers + SetUpAttackerDefenderAliases(LocationOfSiege) ;shoves soldiers into Attacker/Defender aliases depending on the player's faction and which faction is attacking + + LogAttackDefenderAliases() ;for debugging + + DoneSettingUpAliases = true + +EndFunction + +function TurnOnAliases(bool IsAttackQuest) + DoneTurningOnAliases = false + +; CWScript.Log("CWSiegeScript", self + "calling TurnOnAliases()") + + EnableAttackerDefenderAliases() ;Enables the Attacker/Defender aliases + ResetAttackerDefenderAliases() ;Resets the Attacker/Defender aliases + + EnableGenericAliases() ;Enables anything put into the Generic Alias "array" by RegisterGenericAliases() + ResetGenericAliases() ;Resets anything put into the Generic Alias "array" by RegisterGenericAliases() + + if IsAttackQuest + EnableGenericAttackAliases() ;Enables anything put into the Generic Attack Alias "array" by RegisterGenericAttackAliases() + ResetGenericAttackAliases() ;Resets anything put into the Generic Attack Alias "array" by RegisterGenericAttackAliases() + Else + EnableGenericDefendAliases() ;Enables anything put into the Generic Defend Alias "array" by RegisterGenericDefendAliases() + ResetGenericDefendAliases() ;Resets anything put into the Generic Defend Alias "array" by RegisterGenericDefendAliases() + EndIf + + DoneTurningOnAliases = true + +EndFunction + +Function LogAttackDefenderAliases() + logAlias(Attacker1) + logAlias(Attacker2) + logAlias(Attacker3) + logAlias(Attacker4) + logAlias(Attacker5) + logAlias(Attacker6) + logAlias(Attacker7) + logAlias(Attacker8) + logAlias(Attacker9) + logAlias(Attacker10) + + logAlias(Defender1) + logAlias(Defender2) + logAlias(Defender3) + logAlias(Defender4) + logAlias(Defender5) + logAlias(Defender6) + logAlias(Defender7) + logAlias(Defender8) + logAlias(Defender9) + logAlias(Defender10) + +EndFunction + +function logAlias(ReferenceAlias AliasToPrintToLog) +; CWScript.Log("CWSiegeScript", self + "logAlias()" + AliasToPrintToLog + " is REFERENCE " + AliasToPrintToLog.GetReference()) +EndFunction + +Function SetUpAttackerDefenderAliases(Location LocationOfSiege) + +; CWScript.Log("CWSiegeScript", self + "calling SetUpAttackerDefenderAliases()") + + if CWs.playerAllegiance == CWs.iImperials + if CWs.IsPlayerAttacking(LocationOfSiege) + SetUpAliasesImperialsAttacking() + + else ;playerAllegiance == Imperials, but Sons are attacking + SetUpAliasesSonsAttacking() + + endif + + Elseif CWs.playerAllegiance == 2 ;Sons + if CWs.IsPlayerAttacking(LocationOfSiege) + SetUpAliasesSonsAttacking() + + else ;playerAllegiance == Sons, but Imperials are attakcing + SetUpAliasesImperialsAttacking() + + endif + + Else ;unexpected player allegiance +; CWScript.Log("CWSiege", self + "WARNING: SetUpAliases() expected 1(Imperials) or 2(Sons) for CWs.PlayerAllegiance, got: " + CWs.PlayerAllegiance, 2) + + endif + +EndFunction + + +function SetUpAliasesImperialsAttacking() +; CWScript.Log("CWSiegeScript", self + "calling SetUpAliasesImperialsAttacking()") + Attacker1.ForceRefTo(ImperialAttacker1.GetReference()) + Attacker2.ForceRefTo(ImperialAttacker2.GetReference()) + Attacker3.ForceRefTo(ImperialAttacker3.GetReference()) + Attacker4.ForceRefTo(ImperialAttacker4.GetReference()) + Attacker5.ForceRefTo(ImperialAttacker5.GetReference()) + Attacker6.ForceRefTo(ImperialAttacker6.GetReference()) + Attacker7.ForceRefTo(ImperialAttacker7.GetReference()) + Attacker8.ForceRefTo(ImperialAttacker8.GetReference()) + Attacker9.ForceRefTo(ImperialAttacker9.GetReference()) + Attacker10.ForceRefTo(ImperialAttacker10.GetReference()) + + Defender1.ForceRefTo(SonsDefender1.GetReference()) + Defender2.ForceRefTo(SonsDefender2.GetReference()) + Defender3.ForceRefTo(SonsDefender3.GetReference()) + Defender4.ForceRefTo(SonsDefender4.GetReference()) + Defender5.ForceRefTo(SonsDefender5.GetReference()) + Defender6.ForceRefTo(SonsDefender6.GetReference()) + Defender7.ForceRefTo(SonsDefender7.GetReference()) + Defender8.ForceRefTo(SonsDefender8.GetReference()) + Defender9.ForceRefTo(SonsDefender9.GetReference()) + Defender10.ForceRefTo(SonsDefender10.GetReference()) +EndFunction + +function SetUpAliasesSonsAttacking() +; CWScript.Log("CWSiegeScript", self + "calling SetUpAliasesSonsAttacking()") + Attacker1.ForceRefTo(SonsAttacker1.GetReference()) + Attacker2.ForceRefTo(SonsAttacker2.GetReference()) + Attacker3.ForceRefTo(SonsAttacker3.GetReference()) + Attacker4.ForceRefTo(SonsAttacker4.GetReference()) + Attacker5.ForceRefTo(SonsAttacker5.GetReference()) + Attacker6.ForceRefTo(SonsAttacker6.GetReference()) + Attacker7.ForceRefTo(SonsAttacker7.GetReference()) + Attacker8.ForceRefTo(SonsAttacker8.GetReference()) + Attacker9.ForceRefTo(SonsAttacker9.GetReference()) + Attacker10.ForceRefTo(SonsAttacker10.GetReference()) + + Defender1.ForceRefTo(ImperialDefender1.GetReference()) + Defender2.ForceRefTo(ImperialDefender2.GetReference()) + Defender3.ForceRefTo(ImperialDefender3.GetReference()) + Defender4.ForceRefTo(ImperialDefender4.GetReference()) + Defender5.ForceRefTo(ImperialDefender5.GetReference()) + Defender6.ForceRefTo(ImperialDefender6.GetReference()) + Defender7.ForceRefTo(ImperialDefender7.GetReference()) + Defender8.ForceRefTo(ImperialDefender8.GetReference()) + Defender9.ForceRefTo(ImperialDefender9.GetReference()) + Defender10.ForceRefTo(ImperialDefender10.GetReference()) +EndFunction + +function tryToDisableAlias(ReferenceAlias AliasToTry) + ObjectReference AliasRef + + if AliasToTry + AliasRef = AliasToTry.GetReference() + + if AliasRef +; CWScript.Log("CWSiegeScript", self + "tryToDisableAlias([" + AliasToTry +"]) disabling: " + AliasRef) + AliasRef.Disable() + endif + + EndIf + +EndFunction + +function tryToEnableAlias(ReferenceAlias AliasToTry) + ObjectReference AliasRef + + if AliasToTry + AliasRef = AliasToTry.GetReference() + + if AliasRef +; CWScript.Log("CWSiegeScript", self + "tryToEnableAlias([" + AliasToTry +"]) enabling: " + AliasRef) + AliasRef.Enable() + endif + + EndIf + +EndFunction + +function tryToResetAlias(ReferenceAlias AliasToTry) + ObjectReference AliasRef + + if AliasToTry + AliasRef = AliasToTry.GetReference() + + if AliasRef +; CWScript.Log("CWSiegeScript", self + "tryToResetAlias([" + AliasToTry +"]) reseting: " + AliasRef) + AliasRef.Reset() + endif + + EndIf + +EndFunction + + +Function DisableImperialSonsAliases() +; CWScript.Log("CWSiegeScript", self + "calling DisableImperialSonsAliases()") + tryToDisableAlias(ImperialAttacker1) + tryToDisableAlias(ImperialAttacker2) + tryToDisableAlias(ImperialAttacker3) + tryToDisableAlias(ImperialAttacker4) + tryToDisableAlias(ImperialAttacker5) + tryToDisableAlias(ImperialAttacker6) + tryToDisableAlias(ImperialAttacker7) + tryToDisableAlias(ImperialAttacker8) + tryToDisableAlias(ImperialAttacker9) + tryToDisableAlias(ImperialAttacker10) + + tryToDisableAlias(ImperialDefender1) + tryToDisableAlias(ImperialDefender2) + tryToDisableAlias(ImperialDefender3) + tryToDisableAlias(ImperialDefender4) + tryToDisableAlias(ImperialDefender5) + tryToDisableAlias(ImperialDefender6) + tryToDisableAlias(ImperialDefender7) + tryToDisableAlias(ImperialDefender8) + tryToDisableAlias(ImperialDefender9) + tryToDisableAlias(ImperialDefender10) + + tryToDisableAlias(SonsAttacker1) + tryToDisableAlias(SonsAttacker2) + tryToDisableAlias(SonsAttacker3) + tryToDisableAlias(SonsAttacker4) + tryToDisableAlias(SonsAttacker5) + tryToDisableAlias(SonsAttacker6) + tryToDisableAlias(SonsAttacker7) + tryToDisableAlias(SonsAttacker8) + tryToDisableAlias(SonsAttacker9) + tryToDisableAlias(SonsAttacker10) + + tryToDisableAlias(SonsDefender1) + tryToDisableAlias(SonsDefender2) + tryToDisableAlias(SonsDefender3) + tryToDisableAlias(SonsDefender4) + tryToDisableAlias(SonsDefender5) + tryToDisableAlias(SonsDefender6) + tryToDisableAlias(SonsDefender7) + tryToDisableAlias(SonsDefender8) + tryToDisableAlias(SonsDefender9) + tryToDisableAlias(SonsDefender10) + +EndFunction + + +function EnableAttackerDefenderAliases() +; CWScript.Log("CWSiegeScript", self + "calling EnableAttackerDefenderAliases()") + + TryToEnableAlias(Attacker1) + TryToEnableAlias(Attacker2) + TryToEnableAlias(Attacker3) + TryToEnableAlias(Attacker4) + TryToEnableAlias(Attacker5) + TryToEnableAlias(Attacker6) + TryToEnableAlias(Attacker7) + TryToEnableAlias(Attacker8) + TryToEnableAlias(Attacker9) + TryToEnableAlias(Attacker10) + + TryToEnableAlias(Defender1) + TryToEnableAlias(Defender2) + TryToEnableAlias(Defender3) + TryToEnableAlias(Defender4) + TryToEnableAlias(Defender5) + TryToEnableAlias(Defender6) + TryToEnableAlias(Defender7) + TryToEnableAlias(Defender8) + TryToEnableAlias(Defender9) + TryToEnableAlias(Defender10) + +EndFunction + +Function ResetAttackerDefenderAliases() +; CWScript.Log("CWSiegeScript", self + "calling ResetAttackerDefenderAliases()") + + TryToResetAlias(Attacker1) + TryToResetAlias(Attacker2) + TryToResetAlias(Attacker3) + TryToResetAlias(Attacker4) + TryToResetAlias(Attacker5) + TryToResetAlias(Attacker6) + TryToResetAlias(Attacker7) + TryToResetAlias(Attacker8) + TryToResetAlias(Attacker9) + TryToResetAlias(Attacker10) + + TryToResetAlias(Defender1) + TryToResetAlias(Defender2) + TryToResetAlias(Defender3) + TryToResetAlias(Defender4) + TryToResetAlias(Defender5) + TryToResetAlias(Defender6) + TryToResetAlias(Defender7) + TryToResetAlias(Defender8) + TryToResetAlias(Defender9) + TryToResetAlias(Defender10) + +EndFunction + +;Functions to manipulate Generic Aliases "Array" +Function DisableGenericAliases() +; CWScript.Log("CWSiegeScript", self + "calling DisableGenericAliases()") + + TryToDisableAlias(Generic1) + TryToDisableAlias(Generic2) + TryToDisableAlias(Generic3) + TryToDisableAlias(Generic4) + TryToDisableAlias(Generic5) + TryToDisableAlias(Generic6) + TryToDisableAlias(Generic7) + TryToDisableAlias(Generic8) + TryToDisableAlias(Generic9) + TryToDisableAlias(Generic10) + + TryToDisableAlias(Generic11) + TryToDisableAlias(Generic12) + TryToDisableAlias(Generic13) + TryToDisableAlias(Generic14) + TryToDisableAlias(Generic15) + TryToDisableAlias(Generic16) + TryToDisableAlias(Generic17) + TryToDisableAlias(Generic18) + TryToDisableAlias(Generic19) + TryToDisableAlias(Generic20) + + TryToDisableAlias(Generic21) + TryToDisableAlias(Generic22) + TryToDisableAlias(Generic23) + TryToDisableAlias(Generic24) + TryToDisableAlias(Generic25) + TryToDisableAlias(Generic26) + TryToDisableAlias(Generic27) + TryToDisableAlias(Generic28) + TryToDisableAlias(Generic29) + TryToDisableAlias(Generic30) + +EndFunction + +Function EnableGenericAliases() +; CWScript.Log("CWSiegeScript", self + "calling EnableGenericAliases()") + + TryToEnableAlias(Generic1) + TryToEnableAlias(Generic2) + TryToEnableAlias(Generic3) + TryToEnableAlias(Generic4) + TryToEnableAlias(Generic5) + TryToEnableAlias(Generic6) + TryToEnableAlias(Generic7) + TryToEnableAlias(Generic8) + TryToEnableAlias(Generic9) + TryToEnableAlias(Generic10) + + TryToEnableAlias(Generic11) + TryToEnableAlias(Generic12) + TryToEnableAlias(Generic13) + TryToEnableAlias(Generic14) + TryToEnableAlias(Generic15) + TryToEnableAlias(Generic16) + TryToEnableAlias(Generic17) + TryToEnableAlias(Generic18) + TryToEnableAlias(Generic19) + TryToEnableAlias(Generic20) + + TryToEnableAlias(Generic21) + TryToEnableAlias(Generic22) + TryToEnableAlias(Generic23) + TryToEnableAlias(Generic24) + TryToEnableAlias(Generic25) + TryToEnableAlias(Generic26) + TryToEnableAlias(Generic27) + TryToEnableAlias(Generic28) + TryToEnableAlias(Generic29) + TryToEnableAlias(Generic30) + + + +EndFunction + +Function ResetGenericAliases() +; CWScript.Log("CWSiegeScript", self + "calling ResetGenericAliases()") + + TryToResetAlias(Generic1) + TryToResetAlias(Generic2) + TryToResetAlias(Generic3) + TryToResetAlias(Generic4) + TryToResetAlias(Generic5) + TryToResetAlias(Generic6) + TryToResetAlias(Generic7) + TryToResetAlias(Generic8) + TryToResetAlias(Generic9) + TryToResetAlias(Generic10) + + TryToResetAlias(Generic11) + TryToResetAlias(Generic12) + TryToResetAlias(Generic13) + TryToResetAlias(Generic14) + TryToResetAlias(Generic15) + TryToResetAlias(Generic16) + TryToResetAlias(Generic17) + TryToResetAlias(Generic18) + TryToResetAlias(Generic19) + TryToResetAlias(Generic20) + + TryToResetAlias(Generic21) + TryToResetAlias(Generic22) + TryToResetAlias(Generic23) + TryToResetAlias(Generic24) + TryToResetAlias(Generic25) + TryToResetAlias(Generic26) + TryToResetAlias(Generic27) + TryToResetAlias(Generic28) + TryToResetAlias(Generic29) + TryToResetAlias(Generic30) + +EndFunction + + +;Functions to manipulate GenericAttack Aliases "Array" +Function DisableGenericAttackAliases() +; CWScript.Log("CWSiegeScript", self + "calling DisableGenericAttackAliases()") + + TryToDisableAlias(GenericAttack1) + TryToDisableAlias(GenericAttack2) + TryToDisableAlias(GenericAttack3) + TryToDisableAlias(GenericAttack4) + TryToDisableAlias(GenericAttack5) + TryToDisableAlias(GenericAttack6) + TryToDisableAlias(GenericAttack7) + TryToDisableAlias(GenericAttack8) + TryToDisableAlias(GenericAttack9) + TryToDisableAlias(GenericAttack10) + + TryToDisableAlias(GenericAttack11) + TryToDisableAlias(GenericAttack12) + TryToDisableAlias(GenericAttack13) + TryToDisableAlias(GenericAttack14) + TryToDisableAlias(GenericAttack15) + TryToDisableAlias(GenericAttack16) + TryToDisableAlias(GenericAttack17) + TryToDisableAlias(GenericAttack18) + TryToDisableAlias(GenericAttack19) + TryToDisableAlias(GenericAttack20) + + TryToDisableAlias(GenericAttack21) + TryToDisableAlias(GenericAttack22) + TryToDisableAlias(GenericAttack23) + TryToDisableAlias(GenericAttack24) + TryToDisableAlias(GenericAttack25) + TryToDisableAlias(GenericAttack26) + TryToDisableAlias(GenericAttack27) + TryToDisableAlias(GenericAttack28) + TryToDisableAlias(GenericAttack29) + TryToDisableAlias(GenericAttack30) + +EndFunction + +Function EnableGenericAttackAliases() +; CWScript.Log("CWSiegeScript", self + "calling EnableGenericAttackAliases()") + + TryToEnableAlias(GenericAttack1) + TryToEnableAlias(GenericAttack2) + TryToEnableAlias(GenericAttack3) + TryToEnableAlias(GenericAttack4) + TryToEnableAlias(GenericAttack5) + TryToEnableAlias(GenericAttack6) + TryToEnableAlias(GenericAttack7) + TryToEnableAlias(GenericAttack8) + TryToEnableAlias(GenericAttack9) + TryToEnableAlias(GenericAttack10) + + TryToEnableAlias(GenericAttack11) + TryToEnableAlias(GenericAttack12) + TryToEnableAlias(GenericAttack13) + TryToEnableAlias(GenericAttack14) + TryToEnableAlias(GenericAttack15) + TryToEnableAlias(GenericAttack16) + TryToEnableAlias(GenericAttack17) + TryToEnableAlias(GenericAttack18) + TryToEnableAlias(GenericAttack19) + TryToEnableAlias(GenericAttack20) + + TryToEnableAlias(GenericAttack21) + TryToEnableAlias(GenericAttack22) + TryToEnableAlias(GenericAttack23) + TryToEnableAlias(GenericAttack24) + TryToEnableAlias(GenericAttack25) + TryToEnableAlias(GenericAttack26) + TryToEnableAlias(GenericAttack27) + TryToEnableAlias(GenericAttack28) + TryToEnableAlias(GenericAttack29) + TryToEnableAlias(GenericAttack30) + + + +EndFunction + +Function ResetGenericAttackAliases() +; CWScript.Log("CWSiegeScript", self + "calling ResetGenericAttackAliases()") + + TryToResetAlias(GenericAttack1) + TryToResetAlias(GenericAttack2) + TryToResetAlias(GenericAttack3) + TryToResetAlias(GenericAttack4) + TryToResetAlias(GenericAttack5) + TryToResetAlias(GenericAttack6) + TryToResetAlias(GenericAttack7) + TryToResetAlias(GenericAttack8) + TryToResetAlias(GenericAttack9) + TryToResetAlias(GenericAttack10) + + TryToResetAlias(GenericAttack11) + TryToResetAlias(GenericAttack12) + TryToResetAlias(GenericAttack13) + TryToResetAlias(GenericAttack14) + TryToResetAlias(GenericAttack15) + TryToResetAlias(GenericAttack16) + TryToResetAlias(GenericAttack17) + TryToResetAlias(GenericAttack18) + TryToResetAlias(GenericAttack19) + TryToResetAlias(GenericAttack20) + + TryToResetAlias(GenericAttack21) + TryToResetAlias(GenericAttack22) + TryToResetAlias(GenericAttack23) + TryToResetAlias(GenericAttack24) + TryToResetAlias(GenericAttack25) + TryToResetAlias(GenericAttack26) + TryToResetAlias(GenericAttack27) + TryToResetAlias(GenericAttack28) + TryToResetAlias(GenericAttack29) + TryToResetAlias(GenericAttack30) + +EndFunction + +;Functions to manipulate GenericDefend Aliases "Array" +Function DisableGenericDefendAliases() +; CWScript.Log("CWSiegeScript", self + "calling DisableGenericDefendAliases()") + + TryToDisableAlias(GenericDefend1) + TryToDisableAlias(GenericDefend2) + TryToDisableAlias(GenericDefend3) + TryToDisableAlias(GenericDefend4) + TryToDisableAlias(GenericDefend5) + TryToDisableAlias(GenericDefend6) + TryToDisableAlias(GenericDefend7) + TryToDisableAlias(GenericDefend8) + TryToDisableAlias(GenericDefend9) + TryToDisableAlias(GenericDefend10) + + TryToDisableAlias(GenericDefend11) + TryToDisableAlias(GenericDefend12) + TryToDisableAlias(GenericDefend13) + TryToDisableAlias(GenericDefend14) + TryToDisableAlias(GenericDefend15) + TryToDisableAlias(GenericDefend16) + TryToDisableAlias(GenericDefend17) + TryToDisableAlias(GenericDefend18) + TryToDisableAlias(GenericDefend19) + TryToDisableAlias(GenericDefend20) + + TryToDisableAlias(GenericDefend21) + TryToDisableAlias(GenericDefend22) + TryToDisableAlias(GenericDefend23) + TryToDisableAlias(GenericDefend24) + TryToDisableAlias(GenericDefend25) + TryToDisableAlias(GenericDefend26) + TryToDisableAlias(GenericDefend27) + TryToDisableAlias(GenericDefend28) + TryToDisableAlias(GenericDefend29) + TryToDisableAlias(GenericDefend30) + +EndFunction + +Function EnableGenericDefendAliases() +; CWScript.Log("CWSiegeScript", self + "calling EnableGenericDefendAliases()") + + TryToEnableAlias(GenericDefend1) + TryToEnableAlias(GenericDefend2) + TryToEnableAlias(GenericDefend3) + TryToEnableAlias(GenericDefend4) + TryToEnableAlias(GenericDefend5) + TryToEnableAlias(GenericDefend6) + TryToEnableAlias(GenericDefend7) + TryToEnableAlias(GenericDefend8) + TryToEnableAlias(GenericDefend9) + TryToEnableAlias(GenericDefend10) + + TryToEnableAlias(GenericDefend11) + TryToEnableAlias(GenericDefend12) + TryToEnableAlias(GenericDefend13) + TryToEnableAlias(GenericDefend14) + TryToEnableAlias(GenericDefend15) + TryToEnableAlias(GenericDefend16) + TryToEnableAlias(GenericDefend17) + TryToEnableAlias(GenericDefend18) + TryToEnableAlias(GenericDefend19) + TryToEnableAlias(GenericDefend20) + + TryToEnableAlias(GenericDefend21) + TryToEnableAlias(GenericDefend22) + TryToEnableAlias(GenericDefend23) + TryToEnableAlias(GenericDefend24) + TryToEnableAlias(GenericDefend25) + TryToEnableAlias(GenericDefend26) + TryToEnableAlias(GenericDefend27) + TryToEnableAlias(GenericDefend28) + TryToEnableAlias(GenericDefend29) + TryToEnableAlias(GenericDefend30) + + + +EndFunction + +Function ResetGenericDefendAliases() +; CWScript.Log("CWSiegeScript", self + "calling ResetGenericDefendAliases()") + + TryToResetAlias(GenericDefend1) + TryToResetAlias(GenericDefend2) + TryToResetAlias(GenericDefend3) + TryToResetAlias(GenericDefend4) + TryToResetAlias(GenericDefend5) + TryToResetAlias(GenericDefend6) + TryToResetAlias(GenericDefend7) + TryToResetAlias(GenericDefend8) + TryToResetAlias(GenericDefend9) + TryToResetAlias(GenericDefend10) + + TryToResetAlias(GenericDefend11) + TryToResetAlias(GenericDefend12) + TryToResetAlias(GenericDefend13) + TryToResetAlias(GenericDefend14) + TryToResetAlias(GenericDefend15) + TryToResetAlias(GenericDefend16) + TryToResetAlias(GenericDefend17) + TryToResetAlias(GenericDefend18) + TryToResetAlias(GenericDefend19) + TryToResetAlias(GenericDefend20) + + TryToResetAlias(GenericDefend21) + TryToResetAlias(GenericDefend22) + TryToResetAlias(GenericDefend23) + TryToResetAlias(GenericDefend24) + TryToResetAlias(GenericDefend25) + TryToResetAlias(GenericDefend26) + TryToResetAlias(GenericDefend27) + TryToResetAlias(GenericDefend28) + TryToResetAlias(GenericDefend29) + TryToResetAlias(GenericDefend30) + +EndFunction + + +function FailAttackQuest(locationAlias CityAlias) +; CWScript.Log("CWSiegeScript", self + "FailAttackQuest()") + + ;fail the siege quest: + CWs.CWSiegeObj.setStage(8999) + + CWs.FailCWObj(Hold.GetLocation()) + + ;fail the campaign + ;CWs.CWCampaignS.FailedMission = 1 + + CWs.ContestedHoldWinner = CWs.GetDefender(CityAlias.GetLocation()) + + ;CWs.CWCampaign.setStage(255) + + while Game.GetPlayer().IsInLocation(CityAlias.GetLocation()) +; CWScript.Log("CWSiegeScript", self + "FailAttackQuest() Waiting for player to leave City before stoping Siege quest") + utility.wait(5) + endwhile + stop() + +EndFunction + +function FailDefenseQuest(locationAlias CityAlias) +; CWScript.Log("CWSiegeScript", self + "FailDefenseQuest()") + + ;start the escape through the city quest +; CWScript.Log("CWSiegeScript", self + "FailDefenseQuest() CWs.CWEscapeCityStart.SendStoryEvent(" + CityAlias.GetLocation() +")") + CWs.CWEscapeCityStart.SendStoryEvent(CityAlias.GetLocation(), CWs.GetRikkeOrGalmar()) + + +; CWScript.Log("CWSiegeScript", self + "FailDefenseQuest() failing CWSiegeDefendObj quest and failing the campaign") + + ;fail the siege quest: + CWs.CWSiegeObj.setStage(8999) + + CWs.FailCWObj(Hold.GetLocation()) + + + ;Update the campaign objectives + ;CWs.CWCampaignObj.setStage(50) ;objective to flee the city with the Jarl + + ;Fail the campaign + ;CWs.CWCampaignS.FailedMission = 1 + + CWs.ContestedHoldWinner = CWs.GetAttacker(CityAlias.GetLocation()) + + ;CWs.CWCampaign.setstage(255) + + while Game.GetPlayer().IsInLocation(CityAlias.GetLocation()) +; CWScript.Log("CWSiegeScript", self + "FailDefenseQuest() Waiting for player to leave City before stoping Siege quest") + utility.wait(5) + endwhile + stop() + +EndFunction + +Function SucceedDefenseQuest(LocationAlias HoldAlias, LocationAlias CityAlias, ReferenceAlias MainGateExteriorAlias) +;SUCCESS!!! Defenders Win because attackers ran out of respawns +; CWScript.Log("CWSiegeScript", self + "SucceedDefenseQuest()") + +;Removes this music from the stack +MUSCombatCivilWar.Remove() + +;Prevent player activation of main gate into city +MainGateExteriorAlias.GetReference().BlockActivation(FALSE) + +;Set Global Dialog Stuff +CWs.CWStateAttackStarted.SetValue(0) +CWs.CWStateAttackerBrokeThrough.SetValue(0) +CWs.CWStateDefenderFallingBack.SetValue(0) +CWs.CWStateDefenderLastStand.SetValue(0) +CWs.CWStateAttackerAtGate.SetValue(0) +CWs.CWStateAttackerOutOfReinforcements.SetValue(1) + +CWs.CWSiegeObj.setStage(9000) + +;obsolete: +CWs.CompleteCWObj(Hold.GetLocation()) + +CWs.ContestedHoldWinner = CWs.GetDefender(CityAlias.GetLocation()) + +;CWs.registerMissionSuccess() - NOT counting final sieges as successful missions, since those are what increase the CWObj global values + +;CWs.CWCampaign.setStage(255) -- OBSOLETE + +while Game.GetPlayer().IsInLocation(CityAlias.GetLocation()) +; CWScript.Log("CWSiegeScript", self + "SucceedDefenseQuest(): Waiting for player to leave City before stoping Siege quest") + utility.wait(5) +endwhile +stop() + + +EndFunction + + +function TryToTurnOnCatapultAlias(ReferenceAlias CatapultAlias) + ObjectReference CatapultRef = CatapultAlias.GetReference() + + If CatapultRef +; CWScript.Log("CWSiegeScript", self + "TryToTurnOnCatapultAlias() calling turnOn() on " + CatapultRef) + (CatapultRef as CWCatapultScript).turnOn() + Else +; CWScript.Log("CWSiegeScript", self + "TryToTurnOnCatapultAlias() is empty alias, not turning on:" + CatapultAlias) + EndIf + +endfunction + +function TryToturnOffCatapultAlias(ReferenceAlias CatapultAlias) + ObjectReference CatapultRef = CatapultAlias.GetReference() + + If CatapultRef +; CWScript.Log("CWSiegeScript", self + "TryToturnOffCatapultAlias() calling turnOff() on " + CatapultRef) + (CatapultRef as CWCatapultScript).turnOff() + Else +; CWScript.Log("CWSiegeScript", self + "TryToturnOffCatapultAlias() is empty alias, not turning off:" + CatapultAlias) + EndIf + +endfunction + +bool function IsAttack() +; CWScript.Log("CWSiegeScript", self + "IsAttack()") + + return CWs.IsPlayerAttacking(City.GetLocation()) + +EndFunction + +function StartCombatSoundsLoop() + CombatSoundsLoopInstance = AMBCombatSoundsLoop.Play(game.GetPlayer()) + Sound.SetInstanceVolume(CombatSoundsLoopInstance, 0.5) + +EndFunction + +function StopCombatSoundsLoop() + Sound.StopInstance(CombatSoundsLoopInstance) + +EndFunction + +function setupInteriorSiege(Location SiegeLocation, ObjectReference FieldCORef, ObjectReference CityCenterMarker) +; CWScript.Log("CWSiegeScript", self + "setupInteriorSiege(" + SiegeLocation + ")") + + ;start FortSiege + + ;safety check, in case you just finished a fort or capital siege, and before it finished shutting down, started the final battle - highly unlikely, put I can envision happening + int waitingFor + While CWs.CWFortSiegeCapital.IsStopped() == False + waitingFor += 1 + utility.wait(1) + +; CWScript.Log("CWSiegeScript", self + "setupInteriorSiege(" + SiegeLocation + ") WAITING for CWFortSiegeCapital.IsStopped() == false. Have been waiting for:" + waitingFor, 1, true, true) + + ;this is important enough to make sure even if we aren't explicitly testing in Civil War debug mode we get a message about it +; debug.trace(self + "CWSiegeScript: setupInteriorSiege(" + SiegeLocation + ") WAITING for CWFortSiegeCapital.IsStopped() == false. Have been waiting for:" + waitingFor, 1) + EndWhile + + + CWs.CWFortSiegeSpecialStart.SendStoryEventAndWait(SiegeLocation, FieldCORef, CityCenterMarker, aiValue1 = 3) + CWs.CWFinaleStart.SendStoryEvent(SiegeLocation) + +EndFunction + +function ToggleOffComplexWIInteractions(LocationAlias LocationAliasToToggle) +; CWScript.Log("CWSiegeScript", self + "ToggleOffComplexWIInteractions(" + LocationAliasToToggle + ") calling function on CWScript") + CWs.ToggleOffComplexWIInteractions(LocationAliasToToggle) + +EndFunction + +function ToggleOnComplexWIInteractions(LocationAlias LocationAliasToToggle) +; CWScript.Log("CWSiegeScript", self + "ToggleOnComplexWIInteractions(" + LocationAliasToToggle + ") calling function on CWScript") + CWs.ToggleOnComplexWIInteractions(LocationAliasToToggle) + +EndFunction + + +scene Property CWAttackerStartingScene Auto +scene Property CWSiegeDefenderStartingScene Auto + +Quest Property CWPrepareCity Auto + +sound Property AMBCivilWarBattleDistantLP Auto + +sound Property AMBCivilWarBattleStart Auto + +sound Property AMBCivilWarBattleStartDistant Auto + +ObjectReference Property WhiterunAmbExt01 Auto + +ObjectReference Property WhiterunAmbExt02 Auto + +int Property AMBDistantBattleSoundInstance Auto +{Don't assign a number, gets one when the sound is played as a way to refer to it} +int Property AMBDistantBattleStartInstance Auto +{Don't assign a number, gets one when the sound is played as a way to refer to it} +int Property AMBCloseBattleSoundInstance Auto +{Don't assign a number, gets one when the sound is played as a way to refer to it} + + +ObjectReference Property WhiterunAmbExt03 Auto + +GlobalVariable Property CWDistantCatapultsAMB Auto diff --git a/source/scripts/cwthreatcombatbarksscript.psc b/source/scripts/cwthreatcombatbarksscript.psc new file mode 100644 index 00000000..6a1768f9 --- /dev/null +++ b/source/scripts/cwthreatcombatbarksscript.psc @@ -0,0 +1,529 @@ +Scriptname CWThreatCombatBarksScript extends Quest Conditional + +ReferenceAlias Property ImperialBridge Auto + +ReferenceAlias Property ImperialFence Auto +ReferenceAlias Property ImperialFenceArcher Auto +ReferenceAlias Property ImperialFenceMage Auto + +ReferenceAlias Property ImperialHouse Auto + +ReferenceAlias Property ImperialRock Auto + +ReferenceAlias Property ImperialStables Auto + +ReferenceAlias Property ImperialTower Auto +ReferenceAlias Property ImperialTowerArcher Auto +ReferenceAlias Property ImperialTowerMage Auto + +ReferenceAlias Property ImperialTree Auto + +ReferenceAlias Property ImperialWall Auto +ReferenceAlias Property ImperialWallArcher Auto +ReferenceAlias Property ImperialWallMage Auto + +ReferenceAlias Property ImperialWindow Auto +ReferenceAlias Property ImperialWindowArcher Auto +ReferenceAlias Property ImperialWindowMage Auto + + +ReferenceAlias Property SonsBridge Auto + +ReferenceAlias Property SonsFence Auto +ReferenceAlias Property SonsFenceArcher Auto +ReferenceAlias Property SonsFenceMage Auto + +ReferenceAlias Property SonsHouse Auto + +ReferenceAlias Property SonsRock Auto + +ReferenceAlias Property SonsStables Auto + +ReferenceAlias Property SonsTower Auto +ReferenceAlias Property SonsTowerArcher Auto +ReferenceAlias Property SonsTowerMage Auto + +ReferenceAlias Property SonsTree Auto + +ReferenceAlias Property SonsWall Auto +ReferenceAlias Property SonsWallArcher Auto +ReferenceAlias Property SonsWallMage Auto + +ReferenceAlias Property SonsWindow Auto +ReferenceAlias Property SonsWindowArcher Auto +ReferenceAlias Property SonsWindowMage Auto + + + +keyword Property CW1MeleeClose Auto +keyword Property CW1MeleeWide Auto +keyword Property CW1MissileClose Auto +keyword Property CW1MissileWide Auto + +keyword Property CW2MeleeClose Auto +keyword Property CW2MeleeWide Auto +keyword Property CW2MissileClose Auto +keyword Property CW2MissileWide Auto + +keyword Property CW3MeleeClose Auto +keyword Property CW3MeleeWide Auto +keyword Property CW3MissileClose Auto +keyword Property CW3MissileWide Auto + +keyword Property CW4MeleeClose Auto +keyword Property CW4MeleeWide Auto +keyword Property CW4MissileClose Auto +keyword Property CW4MissileWide Auto + +keyword Property CW5MeleeClose Auto +keyword Property CW5MeleeWide Auto +keyword Property CW5MissileClose Auto +keyword Property CW5MissileWide Auto + + +;CWThreatBridgeImperial +;CWThreatBridgeSons + +;CWThreatFenceImperial +;CWThreatFenceImperialArcher +;CWThreatFenceImperialMage +;CWThreatFenceSons +;CWThreatFenceSonsArcher +;CWThreatFenceSonsMage + +;CWThreatHouseImperial +;CWThreatHouseSons + +;CWThreatRockImperial +;CWThreatRockSons + +;CWThreatStablesImperial +;CWThreatStablesSons + +;CWThreatTowerImperial +;CWThreatTowerImperialArcher +;CWThreatTowerImperialMage +;CWThreatTowerSons +;CWThreatTowerSonsArcher +;CWThreatTowerSonsMage + +;CWThreatTreeImperial +;CWThreatTreeSons + +;CWThreatWallImperial +;CWThreatWallImperialArcher +;CWThreatWallImperialMage +;CWThreatWallSons +;CWThreatWallSonsArcher +;CWThreatWallSonsMage + +;CWThreatWindowImperial +;CWThreatWindowImperialArcher +;CWThreatWindowImperialMage +;CWThreatWindowSons +;CWThreatWindowSonsArcher +;CWThreatWindowSonsMage + + + + + +CWScript Property CWs Auto +{BASE OBJECT - pointer to CWScript on CW quest} + +int BattlePhaseToStopBarking = 6 ;once we are in phase 6, we should stop taunting using the combat barks - stage 6 occurs in stage 50 of CWSiege + + +Function ProcessTriggerActor(Actor TriggerActor, float BattlePhase, bool Bridge = false, bool Fence = false, bool House = false, bool Rock = false, bool Stables = false, bool Tower = false, bool Tree = false, bool Wall = false, bool Window = false) +{Trigger calls this function, passing in it's reference. We decide what do to with it.} + +;*** +;debug.StartStackProfiling() + +; CWScript.Log("CWThreatCombatBarksScript", self + "ProcessTriggerActor(" + TriggerActor + ", BattlePhase:" + BattlePhase + ")") + + if BattlePhase >= BattlePhaseToStopBarking +; CWScript.Log("CWThreatCombatBarksScript", self + "ProcessTriggerActor() BattlePhase[" + BattlePhase + "] => BattlePhaseToStopBarking[" + BattlePhaseToStopBarking + "], returning without processing trigger actor.") + return + EndIf + + + ReferenceAlias FactionTypeAlias + ReferenceAlias FactionTypeRoleAlias + GlobalVariable FactionTypeGlobal + GlobalVariable FactionTypeRoleGlobal + + int ActorAllegiance = CWs.GetActorAllgeiance(TriggerActor) + + + + + if ActorAllegiance == CWs.iImperials + if Bridge + FactionTypeAlias = ImperialBridge + FactionTypeGlobal = CWs.CWThreatBridgeImperial + + ElseIf Fence + FactionTypeAlias = ImperialFence + FactionTypeGlobal = CWs.CWThreatFenceImperial + + FactionTypeRoleAlias = determineRoleAlias(TriggerActor, BattlePhase, ImperialFenceArcher, ImperialFenceMage) + FactionTypeRoleGlobal = determineRoleGlobal(TriggerActor, BattlePhase, CWs.CWThreatFenceImperialArcher, CWs.CWThreatFenceImperialMage) + + + ElseIf House + FactionTypeAlias = ImperialHouse + FactionTypeGlobal = CWs.CWThreatHouseImperial + + ElseIf Rock + FactionTypeAlias = ImperialRock + FactionTypeGlobal = CWs.CWThreatRockImperial + + ElseIf Stables + FactionTypeAlias = ImperialStables + FactionTypeGlobal = CWs.CWThreatStablesImperial + + ElseIf Tower + FactionTypeAlias = ImperialTower + FactionTypeGlobal = CWs.CWThreatTowerImperial + + FactionTypeRoleAlias = determineRoleAlias(TriggerActor, BattlePhase, ImperialTowerArcher, ImperialTowerMage) + FactionTypeRoleGlobal = determineRoleGlobal(TriggerActor, BattlePhase, CWs.CWThreatTowerImperialArcher, CWs.CWThreatTowerImperialMage) + + + ElseIf Tree + FactionTypeAlias = ImperialTree + FactionTypeGlobal = CWs.CWThreatTreeImperial + + ElseIf Wall + FactionTypeAlias = ImperialWall + FactionTypeGlobal = CWs.CWThreatWallImperial + + FactionTypeRoleAlias = determineRoleAlias(TriggerActor, BattlePhase, ImperialWallArcher, ImperialWallMage) + FactionTypeRoleGlobal = determineRoleGlobal(TriggerActor, BattlePhase, CWs.CWThreatWallImperialArcher, CWs.CWThreatWallImperialMage) + + + ElseIf Window + FactionTypeAlias = ImperialWindow + FactionTypeGlobal = CWs.CWThreatWindowImperial + + FactionTypeRoleAlias = determineRoleAlias(TriggerActor, BattlePhase, ImperialWindowArcher, ImperialWindowMage) + FactionTypeRoleGlobal = determineRoleGlobal(TriggerActor, BattlePhase, CWs.CWThreatWindowImperialArcher, CWs.CWThreatWindowImperialMage) + + + EndIf + + elseif ActorAllegiance == CWs.iSons + if Bridge + FactionTypeAlias = SonsBridge + FactionTypeGlobal = CWs.CWThreatBridgeSons + + ElseIf Fence + FactionTypeAlias = SonsFence + FactionTypeGlobal = CWs.CWThreatFenceSons + + FactionTypeRoleAlias = determineRoleAlias(TriggerActor, BattlePhase, SonsFenceArcher, SonsFenceMage) + FactionTypeRoleGlobal = determineRoleGlobal(TriggerActor, BattlePhase, CWs.CWThreatFenceSonsArcher, CWs.CWThreatFenceSonsMage) + + + ElseIf House + FactionTypeAlias = SonsHouse + FactionTypeGlobal = CWs.CWThreatHouseSons + + ElseIf Rock + FactionTypeAlias = SonsRock + FactionTypeGlobal = CWs.CWThreatRockSons + + ElseIf Stables + FactionTypeAlias = SonsStables + FactionTypeGlobal = CWs.CWThreatStablesSons + + ElseIf Tower + FactionTypeAlias = SonsTower + FactionTypeGlobal = CWs.CWThreatTowerSons + + FactionTypeRoleAlias = determineRoleAlias(TriggerActor, BattlePhase, SonsTowerArcher, SonsTowerMage) + FactionTypeRoleGlobal = determineRoleGlobal(TriggerActor, BattlePhase, CWs.CWThreatTowerSonsArcher, CWs.CWThreatTowerSonsMage) + + + ElseIf Tree + FactionTypeAlias = SonsTree + FactionTypeGlobal = CWs.CWThreatTreeSons + + ElseIf Wall + FactionTypeAlias = SonsWall + FactionTypeGlobal = CWs.CWThreatWallSons + + FactionTypeRoleAlias = determineRoleAlias(TriggerActor, BattlePhase, SonsWallArcher, SonsWallMage) + FactionTypeRoleGlobal = determineRoleGlobal(TriggerActor, BattlePhase, CWs.CWThreatWallSonsArcher, CWs.CWThreatWallSonsMage) + + + ElseIf Window + FactionTypeAlias = SonsWindow + FactionTypeGlobal = CWs.CWThreatWindowSons + + FactionTypeRoleAlias = determineRoleAlias(TriggerActor, BattlePhase, SonsWindowArcher, SonsWindowMage) + FactionTypeRoleGlobal = determineRoleGlobal(TriggerActor, BattlePhase, CWs.CWThreatWindowSonsArcher, CWs.CWThreatWindowSonsMage) + + + EndIf + + endif + + If BattlePhase == CWs.CWBattlePhase.GetValue() + + FactionTypeAlias.ForceRefTo(TriggerActor) + FactionTypeGlobal.setValue(1) + + if FactionTypeRoleAlias + FactionTypeRoleAlias.ForceRefTo(TriggerActor) + FactionTypeRoleGlobal.setValue(1) + EndIf + +; CWScript.Log("CWThreatCombatBarksScript", self + "ProcessTriggerActor(" + TriggerActor + ", forced into:" + FactionTypeAlias + ", AND " + FactionTypeRoleAlias + ") and the following globals were set to 1:" + FactionTypeGlobal + " AND " + FactionTypeRoleGlobal) + + Else + ;this took too long and we are in the wrong phase, we can't be sure this guy's role hasn't changed, dump the alias. + + EndIf + + +;*** +;debug.StopStackProfiling() + +EndFunction + +ReferenceAlias function determineRoleAlias(Actor ActorToCheck, Float BattlePhase, ReferenceAlias TypeArcherAlias, ReferenceAlias TypeMageAlias) + if isArcher(ActorToCheck, BattlePhase) + return TypeArcherAlias + + ElseIf isMage(ActorToCheck, BattlePhase) + return TypeMageAlias + + Else + return None + EndIf + +EndFunction + +GlobalVariable function determineRoleGlobal(Actor ActorToCheck, Float BattlePhase, GlobalVariable TypeArcherGlobal, GlobalVariable TypeMageGlobal) + if isArcher(ActorToCheck, BattlePhase) + return TypeArcherGlobal + + ElseIf isMage(ActorToCheck, BattlePhase) + return TypeMageGlobal + + Else + return None + EndIf + +EndFunction + +bool function isArcher(Actor ActorToCheck, float BattlePhase) + + bool returnVal + + if BattlePhase == 1 && ( ActorToCheck.GetLinkedRef(CW1MissileClose) || ActorToCheck.GetLinkedRef(CW1MissileWide) ) + returnVal = True + elseif BattlePhase == 2 && ( ActorToCheck.GetLinkedRef(CW2MissileClose) || ActorToCheck.GetLinkedRef(CW2MissileWide) ) + returnVal = True + elseif BattlePhase == 3 && ( ActorToCheck.GetLinkedRef(CW3MissileClose) || ActorToCheck.GetLinkedRef(CW3MissileWide) ) + returnVal = True + elseif BattlePhase == 4 && ( ActorToCheck.GetLinkedRef(CW4MissileClose) || ActorToCheck.GetLinkedRef(CW4MissileWide) ) + returnVal = True + elseif BattlePhase == 5 && ( ActorToCheck.GetLinkedRef(CW5MissileClose) || ActorToCheck.GetLinkedRef(CW5MissileWide) ) + returnVal = True + Else +; CWScript.Log("CWThreatCombatBarksScript", self + "isArcher(" + ActorToCheck + ") didn't find a linkedRef with a CWXMissileClose/Wide keyword where X was the BattlePhase:" + BattlePhase) + + EndIf + + return returnVal + +EndFunction + +bool function isMage(Actor ActorToCheck, float BattlePhase) + + ;currently there are no mages + return False + +EndFunction + +function ClearAliasIfActorIsInIt(ReferenceAlias AliasToCheck, Actor ActorToCheck, GlobalVariable GlobalToClear) + if AliasToCheck.GetReference() == ActorToCheck + + GlobalToClear.SetValue(0) + AliasToCheck.Clear() +; CWScript.Log("CWThreatCombatBarksScript", self + "ClearAliasIfActorIsInIt(" + AliasToCheck + ", " + ActorToCheck + ") actor is in alias, so cleared alias and set global to 0:" + GlobalToClear) + EndIf + +EndFunction + + + +function ProcessTriggerActorLeaving(Actor TriggerActor) + +;*** +;debug.StartStackProfiling() + + + int ActorAllegiance = CWs.GetActorAllgeiance(TriggerActor) + + if ActorAllegiance == CWs.iImperials + + ClearAliasIfActorIsInIt(ImperialBridge, TriggerActor, CWs.CWThreatBridgeImperial) + + ClearAliasIfActorIsInIt(ImperialFence, TriggerActor, CWs.CWThreatFenceImperial) + ClearAliasIfActorIsInIt(ImperialFenceArcher, TriggerActor, CWs.CWThreatFenceImperialArcher) + ClearAliasIfActorIsInIt(ImperialFenceMage, TriggerActor, CWs.CWThreatFenceImperialMage) + + ClearAliasIfActorIsInIt(ImperialHouse, TriggerActor, CWs.CWThreatHouseImperial) + + ClearAliasIfActorIsInIt(ImperialRock, TriggerActor, CWs.CWThreatRockImperial) + + ClearAliasIfActorIsInIt(ImperialStables, TriggerActor, CWs.CWThreatStablesImperial) + + ClearAliasIfActorIsInIt(ImperialTower, TriggerActor, CWs.CWThreatTowerImperial) + ClearAliasIfActorIsInIt(ImperialTowerArcher, TriggerActor, CWs.CWThreatTowerImperialArcher) + ClearAliasIfActorIsInIt(ImperialTowerMage, TriggerActor, CWs.CWThreatTowerImperialMage) + + ClearAliasIfActorIsInIt(ImperialTree, TriggerActor, CWs.CWThreatTreeImperial) + + ClearAliasIfActorIsInIt(ImperialWall, TriggerActor, CWs.CWThreatWallImperial) + ClearAliasIfActorIsInIt(ImperialWallArcher, TriggerActor, CWs.CWThreatWallImperialArcher) + ClearAliasIfActorIsInIt(ImperialWallMage, TriggerActor, CWs.CWThreatWallImperialMage) + + ClearAliasIfActorIsInIt(ImperialWindow, TriggerActor, CWs.CWThreatWindowImperial) + ClearAliasIfActorIsInIt(ImperialWindowArcher, TriggerActor, CWs.CWThreatWindowImperialArcher) + ClearAliasIfActorIsInIt(ImperialWindowMage, TriggerActor, CWs.CWThreatWindowImperialMage) + + elseif ActorAllegiance == CWs.iSons + + ClearAliasIfActorIsInIt(SonsBridge, TriggerActor, CWs.CWThreatBridgeSons) + + ClearAliasIfActorIsInIt(SonsFence, TriggerActor, CWs.CWThreatFenceSons) + ClearAliasIfActorIsInIt(SonsFenceArcher, TriggerActor, CWs.CWThreatFenceSonsArcher) + ClearAliasIfActorIsInIt(SonsFenceMage, TriggerActor, CWs.CWThreatFenceSonsMage) + + ClearAliasIfActorIsInIt(SonsHouse, TriggerActor, CWs.CWThreatHouseSons) + + ClearAliasIfActorIsInIt(SonsRock, TriggerActor, CWs.CWThreatRockSons) + + ClearAliasIfActorIsInIt(SonsStables, TriggerActor, CWs.CWThreatStablesSons) + + ClearAliasIfActorIsInIt(SonsTower, TriggerActor, CWs.CWThreatTowerSons) + ClearAliasIfActorIsInIt(SonsTowerArcher, TriggerActor, CWs.CWThreatTowerSonsArcher) + ClearAliasIfActorIsInIt(SonsTowerMage, TriggerActor, CWs.CWThreatTowerSonsMage) + + ClearAliasIfActorIsInIt(SonsTree, TriggerActor, CWs.CWThreatTreeSons) + + ClearAliasIfActorIsInIt(SonsWall, TriggerActor, CWs.CWThreatWallSons) + ClearAliasIfActorIsInIt(SonsWallArcher, TriggerActor, CWs.CWThreatWallSonsArcher) + ClearAliasIfActorIsInIt(SonsWallMage, TriggerActor, CWs.CWThreatWallSonsMage) + + ClearAliasIfActorIsInIt(SonsWindow, TriggerActor, CWs.CWThreatWindowSons) + ClearAliasIfActorIsInIt(SonsWindowArcher, TriggerActor, CWs.CWThreatWindowSonsArcher) + ClearAliasIfActorIsInIt(SonsWindowMage, TriggerActor, CWs.CWThreatWindowSonsMage) + + EndIf + +;*** +;debug.StopStackProfiling() + +EndFunction + + +;Called by sieges when the battle phase changes +function RegisterBattlePhaseChanged() + + CWs.CWThreatBridgeImperial.SetValue(0) + CWs.CWThreatBridgeSons.SetValue(0) + CWs.CWThreatFenceImperial.SetValue(0) + CWs.CWThreatFenceImperialArcher.SetValue(0) + CWs.CWThreatFenceImperialMage.SetValue(0) + CWs.CWThreatFenceSons.SetValue(0) + CWs.CWThreatFenceSonsArcher.SetValue(0) + CWs.CWThreatFenceSonsMage.SetValue(0) + CWs.CWThreatHouseImperial.SetValue(0) + CWs.CWThreatHouseSons.SetValue(0) + CWs.CWThreatRockImperial.SetValue(0) + CWs.CWThreatRockSons.SetValue(0) + CWs.CWThreatStablesImperial.SetValue(0) + CWs.CWThreatStablesSons.SetValue(0) + CWs.CWThreatTowerImperial.SetValue(0) + CWs.CWThreatTowerImperialArcher.SetValue(0) + CWs.CWThreatTowerImperialMage.SetValue(0) + CWs.CWThreatTowerSons.SetValue(0) + CWs.CWThreatTowerSonsArcher.SetValue(0) + CWs.CWThreatTowerSonsMage.SetValue(0) + CWs.CWThreatTreeImperial.SetValue(0) + CWs.CWThreatTreeSons.SetValue(0) + CWs.CWThreatWallImperial.SetValue(0) + CWs.CWThreatWallImperialArcher.SetValue(0) + CWs.CWThreatWallImperialMage.SetValue(0) + CWs.CWThreatWallSons.SetValue(0) + CWs.CWThreatWallSonsArcher.SetValue(0) + CWs.CWThreatWallSonsMage.SetValue(0) + CWs.CWThreatWindowImperial.SetValue(0) + CWs.CWThreatWindowImperialArcher.SetValue(0) + CWs.CWThreatWindowImperialMage.SetValue(0) + CWs.CWThreatWindowSons.SetValue(0) + CWs.CWThreatWindowSonsArcher.SetValue(0) + CWs.CWThreatWindowSonsMage.SetValue(0) + + ImperialBridge.clear() + + ImperialFence.clear() + ImperialFenceArcher.clear() + ImperialFenceMage.clear() + + ImperialHouse.clear() + + ImperialRock.clear() + + ImperialStables.clear() + + ImperialTower.clear() + ImperialTowerArcher.clear() + ImperialTowerMage.clear() + + ImperialTree.clear() + + ImperialWall.clear() + ImperialWallArcher.clear() + ImperialWallMage.clear() + + ImperialWindow.clear() + ImperialWindowArcher.clear() + ImperialWindowMage.clear() + + + SonsBridge.clear() + + SonsFence.clear() + SonsFenceArcher.clear() + SonsFenceMage.clear() + + SonsHouse.clear() + + SonsRock.clear() + + SonsStables.clear() + + SonsTower.clear() + SonsTowerArcher.clear() + SonsTowerMage.clear() + + SonsTree.clear() + + SonsWall.clear() + SonsWallArcher.clear() + SonsWallMage.clear() + + SonsWindow.clear() + SonsWindowArcher.clear() + SonsWindowMage.clear() + + +EndFunction + diff --git a/source/scripts/darkbrotherhood.psc b/source/scripts/darkbrotherhood.psc new file mode 100644 index 00000000..c2fb8ebf --- /dev/null +++ b/source/scripts/darkbrotherhood.psc @@ -0,0 +1,228 @@ +Scriptname DarkBrotherhood extends Quest Conditional + +int Property FirstSet Auto Conditional + +int Property ContractSet Auto Conditional + +int Property NextSet Auto Conditional + +int Property BlackDoorPass Auto Conditional + +int Property AstridNightMotherTalk1 Auto Conditional + +int Property AstridNightMotherTalk2 Auto Conditional + +int Property AstridContractAdvice Auto Conditional + +int Property AstridSanctuaryMove Auto Conditional + +int Property CiceroArrive Auto Conditional + +int Property FirstKill Auto Conditional + +int Property MoreSides Auto Conditional + +int Property DawnstarDoorPass Auto Conditional + +int Property CiceroGone Auto Conditional + +int Property BlackSacrament Auto Conditional + +ReferenceAlias Property pAstrid Auto + +ReferenceAlias Property pVeezara Auto + +ReferenceAlias Property pBabette Auto + +ReferenceAlias Property pGabriella Auto + +ObjectReference Property pAstridMarker Auto + +ReferenceAlias Property pCicero Auto + +ObjectReference Property pNightMotherCoffin Auto + +ReferenceAlias Property pArnbjorn Auto + +ReferenceAlias Property pFestus Auto + +Quest Property DarkDialogueQuest Auto + +ObjectReference Property pAstridCiceroMarker Auto + +ObjectReference Property pCiceroMarker Auto + +ObjectReference Property pArnbjornMarker Auto + +ObjectReference Property pFestusMarker Auto + +ObjectReference Property pVeezaraMarker Auto + +ObjectReference Property pBabetteMarker Auto + +ObjectReference Property pGabriellaMarker Auto + +Quest Property pDB02 Auto + +Quest Property pDB01 Auto + +int Property pTalkBabetteBeforeDB11 Auto Conditional + +int Property pTalkBabetteAfterDB11 Auto Conditional + +int Property pTalkNazirBeforeDB11 Auto Conditional + +int Property pTalkNazirAfterDB11 Auto Conditional + +int Property pPlayerInWindhelm Auto Conditional + +Quest Property pDBEntranceQuest Auto + +Location Property pWindhelmLocation Auto Conditional + +int Property pNazirStartingOut Auto Conditional + +int Property pSanctuaryAstrid Auto Conditional + +int Property pEnnodiusAlreadyDead Auto Conditional +int Property pNarfiAlreadyDead Auto Conditional +int Property pBetildAlreadyDead Auto Conditional +int Property pHernAlreadyDead Auto Conditional +int Property pLurbukAlreadyDead Auto Conditional +int Property pDeekusAlreadyDead Auto Conditional +int Property pMarandrujoAlreadyDead Auto Conditional +int Property pAnoriathAlreadyDead Auto Conditional +int Property pAgnisAlreadyDead Auto Conditional +int Property pMalurilAlreadyDead Auto Conditional +int Property pHelvardAlreadyDead Auto Conditional +int Property pSafiaAlreadyDead Auto Conditional +;CiceroFramed 1=Theft, 2=Assault, 3=Contraband +int Property CiceroFramed Auto Conditional +int Property CiceroGuardResponse Auto Conditional +int Property DB01MiscResolved Auto Conditional +;CiceroSancMood 1=Helped him with Loreius, 2=Didn't help him with Loreius, 3=Never met him before +int Property CiceroSancMood Auto Conditional +int Property AstridCiceroOpinion Auto Conditional +int Property FestusRespect Auto Conditional +int Property CiceroGoneSceneStart Auto Conditional +int Property CiceroDead Auto Conditional +int Property pFirstScene Auto Conditional +Scene Property pFirstArriveScene Auto Conditional +int Property pFirstSceneOver Auto Conditional +int Property pGiveOlavaToken Auto Conditional +int Property SolitudeStormcloaks Auto Conditional +;LoreiusState 1=Good, 2=Bad +int Property LoreiusState Auto Conditional +int Property HavePoison Auto Conditional +int Property CiceroBack Auto Conditional +;CiceroState 1=Not Teammate, 2=Follow, 3=Wait +int Property CiceroState Auto Conditional +int Property CourierDeliver Auto Conditional +int Property pCiceroGuardScene Auto Conditional +ObjectReference Property CourierLetter Auto +int Property CiceroTalk1 Auto Conditional +int Property CiceroTalk2 Auto Conditional +ObjectReference Property DaggerMarkarth Auto +int Property Victim1Secret Auto Conditional +int Property Victim2Secret Auto Conditional +int Property Victim3Secret Auto Conditional +int Property Victim4Secret Auto Conditional +int Property Secret1Found Auto Conditional +int Property Secret2Found Auto Conditional +int Property Secret3Found Auto Conditional +int Property Secret4Found Auto Conditional +;InitiateState 1=Not Teammate, 2=Follow, 3=Wait +int Property Initiate1State Auto Conditional +int Property Initiate2State Auto Conditional +int Property CiceroFollower Auto Conditional +int Property Initiate1Follower Auto Conditional +int Property Initiate2Follower Auto Conditional +int Property TovaDead Auto Conditional +int Property CiceroTalkListener Auto Conditional + + + + +;Event OnInit() + +;RegisterForUpdate(5) + +;EndEvent + + + +Event OnUpdate() +; ; debug.trace(self + "DarkBrotherhoodOnUpdateEvent") +;If AstridSanctuaryMove == 0 + ;If pDB02.GetStage () == 40 + ;If DBDestroy.GetStage () < 10 + ;if Game.GetPlayer().GetCurrentLocation() != pAstrid.GetRef().GetCurrentLocation() + ;pAstrid.GetRef().MoveTo(pAstridMarker) + ;AstridSanctuaryMove = 1 + ;endif + ;endif + ;endif +;endif + +;Enables Cicero and the Night Mother's coffin in the Sanctuary after first side contract completed +if CiceroArrive == 0 + if FirstKill >= 1 + pCicero.GetRef().Enable() + pNightMotherCoffin.Enable() + pAstrid.GetRef().Moveto (pAstridCiceroMarker) + pCicero.GetRef().Moveto (pCiceroMarker) + pArnbjorn.GetRef().Moveto (pArnbjornMarker) + pFestus.GetRef().Moveto (pFestusMarker) + pVeezara.GetRef().Moveto (pVeezaraMarker) + pGabriella.GetRef().Moveto (pGabriellaMarker) + pBabette.GetRef().Moveto (pBabetteMarker) + DarkSanctuaryDialogueScript pDarkDialogueScript = DarkDialogueQuest as DarkSanctuaryDialogueScript + pDarkDialogueScript.BabetteFirstGreet = 1 + pDarkDialogueScript.ArnbjornFirstGreet = 1 + pDarkDialogueScript.GabriellaFirstGreet = 1 + pDarkDialogueScript.VeezaraFirstGreet = 1 + pDarkDialogueScript.FestusFirstGreet = 1 + DaggerMarkarth.Enable() + CiceroArrive = 1 + endif +endif + + +; Starts the DB Entrance quest, and the initializing of the courier, after DB01, and the player leaves Windhelm +If pPlayerInWindhelm == 0 +; ;debug.trace(self + "Player Is Not In Windhelm Var") + If pDB01.GetStage () >= 200 +; ;debug.trace(self + "DB01>200") + If pDB02.GetStage () < 10 +; ;debug.trace(self + "DB02 < 10") + if Game.GetPlayer().IsInLocation (pWindhelmLocation) == 0 +; ;debug.trace(self + "Player Is Not In Windhelm") + pDBEntranceQuestScript EntranceScript = pDBEntranceQuest as pDBEntranceQuestScript + if EntranceScript.pSleepyTime == 0 +; ;debug.trace(self + "SleepyTime is 0") + ;Debug.MessageBox("DBEntranceQuestStarted") + ;pDBEntranceQuest.SetStage (10) + pDBEntranceQuest.SetStage (20) + pPlayerInWindhelm = 1 + endif + endif + endif + endif +endif + + +EndEvent + + + + + +Outfit Property AstridSanctuaryOutfit Auto + +int Property DoorDoOnce Auto + +Quest Property DBDestroy Auto + +ReferenceAlias Property pNazir Auto + +int Property ListenerTopic Auto Conditional diff --git a/source/scripts/darksanctuarydialoguescript.psc b/source/scripts/darksanctuarydialoguescript.psc new file mode 100644 index 00000000..8dacf2a3 --- /dev/null +++ b/source/scripts/darksanctuarydialoguescript.psc @@ -0,0 +1,19 @@ +Scriptname DarkSanctuaryDialogueScript extends Quest Conditional + +int Property AstridFirstGreet Auto Conditional + +int Property FestusFirstGreet Auto Conditional + +int Property NazirFirstGreet Auto Conditional + +int Property GabriellaFirstGreet Auto Conditional + +int Property BabetteFirstGreet Auto Conditional + +int Property CiceroFirstGreet Auto Conditional + +int Property VeezaraFirstGreet Auto Conditional + +int Property ArnbjornFirstGreet Auto Conditional + +int Property FirstSceneComplete Auto Conditional diff --git a/source/scripts/darttrap.psc b/source/scripts/darttrap.psc new file mode 100644 index 00000000..7eca7f41 --- /dev/null +++ b/source/scripts/darttrap.psc @@ -0,0 +1,168 @@ +scriptName DartTrap extends TrapBase +; +;Dart Trap extending TrapBase +;integrated with the TrapTriggerBase +; +;================================================================ + +import debug +import utility +import custom + +int numPorts +objectReference currentLink +int portIndex = 1 +int shotCount +;int numShots = 20 ;might want to make this a property +float fireRate = 0.1 +float property initialDelay = 0.2 auto +weapon dartWeapon +float property firingDelay = 0.03 auto +float currentTime + +int property NumShots =1 auto + +bool property isFiring auto hidden +bool property isLoaded auto hidden + +Function initialize() + currentLink = self as objectReference + numPorts = countLinks(currentLink) ;counts how many in a chain of linked refs. Don't loop linked refs. + ;trace( "numPorts" ) + ;trace( numPorts as string ) + +endFunction + +function ResetLimiter() + shotcount = 0 ;shotCount is scoped outside of the OnActivateBlocks. This will reset scopecount to 0, extending the firing time. +endFunction + +Function fireTrap() + isFiring = True + ResolveLeveledWeapon() + ;TRACE("fireTrap called") + WindupSound.play( self as ObjectReference) ;play windup sound + wait( initialDelay ) ;wait for windup + ;TRACE("Initial Delay complete") + trapDisarmed = fireOnlyOnce ;If this can be fired only once then disarm + + ;TRACE("Looping =") + ;TRACE(Loop) + + shotcount = 0 + currentTime = getCurrentRealTime() + while(shotcount <= numShots ) && isLoaded == TRUE + wait(0.01) + if ((currentTime + firingDelay) < getCurrentRealTime()) + + int firePort = RandomInt( 0, numPorts ) ;set fireport + + if fireport > 0 + currentLink = GetNthLinkedRef (firePort) + Else + currentLink = self as objectReference + endif + dartWeapon.fire( currentLink, dartAmmo ) ;fire + shotcount = shotCount + 1 ;increment number of shotswait( fireRate ) ;- timeDelay) ;wait for the fire rate time delay, minus processing time + + + + if (loop == TRUE) ;Reset Limiter + ResetLimiter() + endif + currentTime = getCurrentRealTime() + endif + endWhile + + if isLoaded + isFiring = false + ;playAnimation("idle") + goToState("Reset") + endif + +endFunction + +State Reset + + Event OnBeginState() + ;TRACE("State Reset") + GoToState ( "Idle" ) + ;TrapHitBase hitBase = (self as objectReference) as TrapHitBase + ;hitBase.goToState("CanHit") + endEvent + + Event OnActivate( objectReference activateRef ) + ;TRACE("Reset trigger") + EndEvent + +endState + +event onCellAttach() + isLoaded = TRUE + if isFiring == True + fireTrap() + endif +EndEvent + +event onCellDetach() +; debug.Trace(self + " has recieved onUnload event") + isLoaded = FALSE +endEvent + +;----------------------------------------------- + +int property LvlThreshold1 auto +weapon property LvlWeapon1 auto +int property LvlThreshold2 auto +weapon property LvlWeapon2 auto +int property LvlThreshold3 auto +weapon property LvlWeapon3 auto +int property LvlThreshold4 auto +weapon property LvlWeapon4 auto +int property LvlThreshold5 auto +weapon property LvlWeapon5 auto +weapon property LvlWeapon6 auto +ammo property dartAmmo auto + +Function ResolveLeveledWeapon () + ;Trace("ResolveLeveledWeapon") + int damageLevel + damageLevel = CalculateEncounterLevel(TrapLevel) + + weapon lvlWeapon = LvlWeapon1 + + if (damageLevel > LvlThreshold1 && damageLevel <= LvlThreshold2) + lvlWeapon = LvlWeapon2 + ;Trace("damage threshold =") + ;Trace("2") + endif + if (damageLevel > LvlThreshold2 && damageLevel <= LvlThreshold3) + lvlWeapon = LvlWeapon3 + ;Trace("damage threshold =") + ;Trace("3") + endif + if (damageLevel > LvlThreshold3 && damageLevel <= LvlThreshold4) + lvlWeapon = LvlWeapon4 + ;Trace("damage threshold =") + ;Trace("4") + endif + if (damageLevel > LvlThreshold4 && damageLevel <= LvlThreshold5) + lvlWeapon = LvlWeapon5 + ;Trace("damage threshold =") + ;Trace("5") + endif + if (damageLevel > LvlThreshold5) + lvlWeapon = LvlWeapon6 + ;Trace("damage threshold =") + ;Trace("6") + endif + + dartWeapon = lvlWeapon +EndFunction + +;Event OnTrapHit(ObjectReference akTarget, float afXVel, float afYVel, float afZVel, float afXPos, float afYPos, float afZPos, int aeMaterial, bool abInitialHit, int aeMotionType) +; if (hitOnce == FALSE) +; hitOnce = TRUE +; endif +;endEvent + diff --git a/source/scripts/defaultactivatelinkdooncescript.psc b/source/scripts/defaultactivatelinkdooncescript.psc new file mode 100644 index 00000000..bba240e0 --- /dev/null +++ b/source/scripts/defaultactivatelinkdooncescript.psc @@ -0,0 +1,44 @@ +ScriptName defaultActivateLinkDoOnceSCRIPT extends objectReference +{Default script intended for triggers. When hit, they'll activate their linked reference} + +import game +import debug + +objectReference property OnlyActor auto +{Set this property if you want to only allow activation from a specific actor, such as the player} + +bool property doOnce auto +{by default, this trigger fires once only.} + +function ActivateNow(objectReference trigRef) +; Debug.Trace("Activating: " + self + " " + myLink) + objectReference myLink = getLinkedRef() + + self.activate(self, true) + if MyLink != NONE + myLink.activate(self as objectReference) + endif + if doOnce == true + gotoState("allDone") + endif +endFunction + +auto STATE waiting + EVENT onTriggerEnter(objectReference actronaut) +; Debug.Trace("Trigger Enter: " + actronaut) + + if !onlyActor + activateNow(actronaut) + endif + + if onlyActor == actronaut + activateNow(actronaut) + endif + + endEVENT +endSTATE + +STATE allDone +;do nothing +endSTATE + \ No newline at end of file diff --git a/source/scripts/defaultactselfonenteronleave.psc b/source/scripts/defaultactselfonenteronleave.psc new file mode 100644 index 00000000..f0c32a49 --- /dev/null +++ b/source/scripts/defaultactselfonenteronleave.psc @@ -0,0 +1,29 @@ +ScriptName defaultActSelfOnEnterOnLeave extends TrapTriggerBase +{Default script that simply activates itself onTriggerEnter and onTriggerLeave} + +import game +import debug + +objectReference property OnlyActor auto +{By default, this property is set to the player} + +auto State waiting + Event onTriggerEnter(objectReference triggerRef) + if !onlyActor + activate(self as ObjectReference) + elseif (onlyActor == triggerRef) + activate(self as ObjectReference) + endif + + endEvent + + Event onTriggerLeave(objectReference triggerRef) + if !onlyActor + activate(self as ObjectReference) + elseif (onlyActor == triggerRef) + activate(self as ObjectReference) + endif + + endEvent +endState + \ No newline at end of file diff --git a/source/scripts/defaultblockactivation.psc b/source/scripts/defaultblockactivation.psc new file mode 100644 index 00000000..14b7299e --- /dev/null +++ b/source/scripts/defaultblockactivation.psc @@ -0,0 +1,8 @@ +Scriptname defaultBlockActivation extends ObjectReference +{This script causes the actor to block activation upon loading.} + +Event OnLoad() + + BlockActivation(true) + +EndEvent diff --git a/source/scripts/defaultblockfolloweractivation.psc b/source/scripts/defaultblockfolloweractivation.psc new file mode 100644 index 00000000..5172fd02 --- /dev/null +++ b/source/scripts/defaultblockfolloweractivation.psc @@ -0,0 +1,6 @@ +ScriptName defaultBlockFollowerActivation extends ObjectReference +{Prevents followers from using this object.} + +Event OnLoad() + Self.SetNoFavorAllowed() +EndEvent \ No newline at end of file diff --git a/source/scripts/defaultbuttonscript.psc b/source/scripts/defaultbuttonscript.psc new file mode 100644 index 00000000..4da6465c --- /dev/null +++ b/source/scripts/defaultbuttonscript.psc @@ -0,0 +1,22 @@ +scriptName defaultButtonSCRIPT extends objectReference +{quick script for a button object.} + +bool property useOnce = FALSE auto +{Can be used only once? Default: FALSE} + +auto STATE active + EVENT onActivate(objectReference actronaut) + ;playAnimationandWait("down") + playAnimation("down") + gotoState("inactive") + activate(self as ObjectReference) + playAnimation("up") + gotoState("active") + endEVENT +endSTATE + +STATE inactive + ; do nothing in this state +endSTATE + +int Property TriggerType Auto diff --git a/source/scripts/defaultcastfromlinkontriggerscript.psc b/source/scripts/defaultcastfromlinkontriggerscript.psc new file mode 100644 index 00000000..07d2ef1e --- /dev/null +++ b/source/scripts/defaultcastfromlinkontriggerscript.psc @@ -0,0 +1,33 @@ +scriptName DefaultCastFromLinkOnTriggerSCRIPT extends objectReference +{Configurable Custom Script. Be default: when triggered, it will cast the spell from a linked ref at the triggering actor} + +bool property playerOnly auto +{if true, only works on the player} +bool property doOnce auto +{fire multiple times?} +float property delayBetween auto +{seconds to wait between shots. Only relevant if doOnce == false} +spell property mySpell auto +{spell to cast onTriggerEnter} + + +auto STATE active + EVENT onTriggerEnter(ObjectReference actronaut) + if playerOnly == true && actronaut == game.getPlayer() || playerOnly == false +; debug.trace("Casting: " + mySpell + " from " + getLinkedRef()) + mySpell.Cast(getLinkedRef()) + gotoState ("inactive") ; don't cast subsequent spells until told to do so + if doOnce == true + ; and don't come back! + else + utility.wait(delayBetween) + gotoState("active") +; debug.trace("Casting from " + getLinkedRef() + " available again") + endif + endif + endEVENT +endSTATE + +STATE inactive + ; nothing happens here. +endSTATE \ No newline at end of file diff --git a/source/scripts/defaultdeleteselfonreset.psc b/source/scripts/defaultdeleteselfonreset.psc new file mode 100644 index 00000000..da2a6b02 --- /dev/null +++ b/source/scripts/defaultdeleteselfonreset.psc @@ -0,0 +1,7 @@ +Scriptname defaultDeleteSelfOnReset extends ObjectReference Hidden +{DOESN'T DO WHAT IT'S NAME IMPLIES. IT'S HAD CHANGES MADE TO IT SPECIFICALLY FOR FIXING A NIRNROOT GLOW ISSUE.} + +EVENT OnCellAttach() + self.Disable() + self.Delete() +endEVENT diff --git a/source/scripts/defaultdisableexitenableenter.psc b/source/scripts/defaultdisableexitenableenter.psc new file mode 100644 index 00000000..db32a29c --- /dev/null +++ b/source/scripts/defaultdisableexitenableenter.psc @@ -0,0 +1,45 @@ +Scriptname DefaultDisableExitEnableEnter extends ObjectReference +{ +Disables LinkedRef(s) on player exit, and re-enables them on enter. +Works with regular linked ref + LinkCustom01-04 keyworded links. +} + +Keyword Property LinkCustom01 Auto +Keyword Property LinkCustom02 Auto +Keyword Property LinkCustom03 Auto +Keyword Property LinkCustom04 Auto + +bool Property shouldFade = TRUE Auto +{Whether the links should fade or not when enabled/disabled. Defaults to TRUE.} + +EVENT onTriggerEnter(objectReference triggerRef) + if triggerRef == Game.GetPlayer() as actor + ObjectReference MyLink = GetLinkedRef() + ObjectReference MyLink01 = GetLinkedRef(LinkCustom01) + ObjectReference MyLink02 = GetLinkedRef(LinkCustom02) + ObjectReference MyLink03 = GetLinkedRef(LinkCustom03) + ObjectReference MyLink04 = GetLinkedRef(LinkCustom04) + + MyLink.Enable(shouldFade) + MyLink01.Enable(shouldFade) + MyLink02.Enable(shouldFade) + MyLink03.Enable(shouldFade) + MyLink04.Enable(shouldFade) + endif +endEVENT + +EVENT onTriggerLeave(objectReference triggerRef) + if triggerRef == Game.GetPlayer() as actor + ObjectReference MyLink = GetLinkedRef() + ObjectReference MyLink01 = GetLinkedRef(LinkCustom01) + ObjectReference MyLink02 = GetLinkedRef(LinkCustom02) + ObjectReference MyLink03 = GetLinkedRef(LinkCustom03) + ObjectReference MyLink04 = GetLinkedRef(LinkCustom04) + + MyLink.Disable(shouldFade) + MyLink01.Disable(shouldFade) + MyLink02.Disable(shouldFade) + MyLink03.Disable(shouldFade) + MyLink04.Disable(shouldFade) + endif +endEVENT \ No newline at end of file diff --git a/source/scripts/defaultdisableonloadaftertrig.psc b/source/scripts/defaultdisableonloadaftertrig.psc new file mode 100644 index 00000000..03514bd7 --- /dev/null +++ b/source/scripts/defaultdisableonloadaftertrig.psc @@ -0,0 +1,26 @@ +Scriptname DefaultDisableOnLoadAfterTrig extends ObjectReference +{This trigger will disable itself on the next load, after it's been triggered.} + + +bool property beenTriggered auto hidden +{If true the player has walked into this trigger} + +EVENT OnLoad() + if beenTriggered + self.disable() + ;utility.trace("DARYL - " + self + " Disabling myself since I've previously been triggered") + else + ;utility.trace("DARYL - " + self + " Not disabling myself since I wasn't previously triggered") + endif +EndEVENT + +EVENT OnTriggerEnter(objectReference triggerRef) + if triggerRef == Game.GetPlayer() + beenTriggered = TRUE + ;utility.trace("DARYL - " + self + " Setting beenTriggered to TRUE since the player walked in the trigger") + else + ;Do nothing since triggerRef wasn't the player + endif +EndEVENT + + \ No newline at end of file diff --git a/source/scripts/defaultdisableotherobjectonactivate.psc b/source/scripts/defaultdisableotherobjectonactivate.psc new file mode 100644 index 00000000..b18c2a55 --- /dev/null +++ b/source/scripts/defaultdisableotherobjectonactivate.psc @@ -0,0 +1,19 @@ +scriptName defaultDisableOtherObjectOnActivate extends ObjectReference +{when this is aquired by the player, disable the objectReference set in the property + This is meant for use with cell reset enabling/disabling} + +objectReference property refToDisable auto + +auto state waiting + Event OnActivate(objectReference akActivator) + if refToDisable.isEnabled() + goToState("Done") + refToDisable.disable() + endif + endEvent +endState + +state Done +endState + + diff --git a/source/scripts/defaultdisableselfonactivate.psc b/source/scripts/defaultdisableselfonactivate.psc new file mode 100644 index 00000000..717f00e5 --- /dev/null +++ b/source/scripts/defaultdisableselfonactivate.psc @@ -0,0 +1,13 @@ +Scriptname defaultDisableSelfOnActivate extends ObjectReference +{for anything that you want to disable itself once it's activated} + +auto STATE WaitingToBeActivated + EVENT OnActivate (objectReference triggerRef) + Disable() + GoToState("Disabled") + EndEvent +EndState + +STATE Disabled + ;done doing stuff +endSTATE diff --git a/source/scripts/defaultdwebuttonscript.psc b/source/scripts/defaultdwebuttonscript.psc new file mode 100644 index 00000000..4fde05dc --- /dev/null +++ b/source/scripts/defaultdwebuttonscript.psc @@ -0,0 +1,24 @@ +scriptName defaultDweButtonScript extends objectReference + +sound property QSTAstrolabeButtonPressX auto +objectReference property objSelf auto hidden + +event onCellAttach() + objSelf = self as objectReference + playAnimation("Open") +endEvent + + +auto state open + event onActivate(objectReference akActivator) + goToState("waiting") + playAnimationAndWait("Trigger01","done") + if QSTAstrolabeButtonPressX + QSTAstrolabeButtonPressX.play(objSelf) + endif + goToState("Open") + endEvent +endState + +state waiting +endState diff --git a/source/scripts/defaultdwegearscript.psc b/source/scripts/defaultdwegearscript.psc new file mode 100644 index 00000000..0f248669 --- /dev/null +++ b/source/scripts/defaultdwegearscript.psc @@ -0,0 +1,42 @@ +scriptName defaultDweGearScript extends objectReference +; + +;string property gearAnim = "loop" auto + +;event onLoad() + ;playAnimation("StartOpen") +;endEvent + +bool property useOffAnim = false auto +{whether to play the off anim when activated a second time + default = false} +bool property off = true auto hidden + +event onLoad() + if off + playAnimation ("startOff") + else + playAnimation ("startLooping") + endif +endEvent + + +auto state off + event onActivate(objectReference akActivator) +; debug.trace (self + "the gear has been turned on") + playAnimation ("fixLoop") + goToState("On") + endEvent +endState + +state on + event onActivate(objectReference akActivator) +; debug.trace (self + "the gear has been turned off") + if useOffAnim + playAnimation ("Off") + else + playAnimation ("fixLoop") + endif + goToState("Off") + endEvent +endState diff --git a/source/scripts/defaultenabledisablelinkedref.psc b/source/scripts/defaultenabledisablelinkedref.psc new file mode 100644 index 00000000..2a09cc71 --- /dev/null +++ b/source/scripts/defaultenabledisablelinkedref.psc @@ -0,0 +1,94 @@ +scriptName defaultEnableDisableLinkedRef extends ObjectReference +{ +- This script enables or disables linked ref based on which type user defines in properties. +- Can be done OnTriggerEnter, or OnActivate, whichever happens first +- This script only fires once then disables itself (default), or can be told to go to a done state (usually for activators) with the ShouldDisable bool. +} + +int property TriggerType auto +{ +0 (default) - enables linked ref +1 - disables linked ref +} + +bool Property PlayerOnly = TRUE auto +{ +Does this only trigger for the player? (DEFAULT = TRUE) +} + +bool Property Fade = FALSE auto +{ +Fade in/out when enabled/disabled? (DEFAULT = FALSE) +} + +bool Property ShouldDisable = TRUE auto +{ +Should I disable once triggered/activated? (DEFAULT = TRUE) +} + +float Property Delay = 0.0 auto +{ +Delay before Enable/Disable (DEFAULT = 0.0) +} + +ObjectReference myLinkedRef + +auto State Waiting + + + Event onTriggerEnter(ObjectReference triggerRef) + + if (triggerRef == Game.GetPlayer()) || (!PlayerOnly) + myLinkedRef = GetLinkedRef() as ObjectReference + + utility.Wait(Delay) + + if (TriggerType == 0) + myLinkedRef.enable(Fade) + elseif (TriggerType == 1) + myLinkedRef.disable(Fade) + endif + + + if (ShouldDisable == TRUE) + self.disable() + else + GoToState("Done") + endif + + endif + + endEvent + + + Event onActivate(ObjectReference triggerRef) + + if (triggerRef == Game.GetPlayer()) || (!PlayerOnly) + myLinkedRef = GetLinkedRef() as ObjectReference + + utility.Wait(Delay) + + if (TriggerType == 0) + myLinkedRef.enable(Fade) + elseif (TriggerType == 1) + myLinkedRef.disable(Fade) + endif + + + if (ShouldDisable == TRUE) + self.disable() + else + GoToState("Done") + endif + + endif + + endEvent + + +endState + + +State Done + ;Do Nothing +endState diff --git a/source/scripts/defaultenablelinkedrefondeath.psc b/source/scripts/defaultenablelinkedrefondeath.psc new file mode 100644 index 00000000..7b8fbccc --- /dev/null +++ b/source/scripts/defaultenablelinkedrefondeath.psc @@ -0,0 +1,31 @@ +Scriptname defaultEnableLinkedRefOnDeath extends Actor +{enable OR disable linked ref on death} + +auto STATE WaitingToBeActivated + EVENT OnDeath(Actor killer) +; ;Debug.Trace("ACTIVATED") + ; get linked ref + ObjectReference myRef = GetLinkedRef(LinkedRefKeyword) + if myRef + GoToState("done") + if bEnableOnActivate + myRef.Enable() + else + myRef.Disable() + endif + endif + EndEvent +EndState + +STATE done + ;done doing stuff +endSTATE + + +bool Property bEnableOnActivate = true Auto +{true (default) = enable linked ref +false = disable linked ref +} + +Keyword Property LinkedRefKeyword Auto +{optional - if supplied, use this for GetLinkedRef} diff --git a/source/scripts/defaultfakenpcloadtrig.psc b/source/scripts/defaultfakenpcloadtrig.psc new file mode 100644 index 00000000..f0ad218e --- /dev/null +++ b/source/scripts/defaultfakenpcloadtrig.psc @@ -0,0 +1,41 @@ +scriptname defaultFakeNPCLoadTRIG extends objectReference +{Script for disabling an NPC when that NPC hits the trigger. Can set a stage when this happens} +;================================================================= +quest property myQuest auto +{the quest, if relevant, this trigger is used for} +int property preRequisiteStage = -1 auto +{if any, stage that must be set for this trigger to function} +int property StageToSet auto +{if any, stage to set when the specified NPC is disabled by hitting this trigger} +actorBase property NPCtoDisable auto +{NPC is disabled on trigger. Intention is to fake a load door} +;================================================================= +auto STATE waiting + EVENT onTriggerEnter(objectReference actronaut) +; debug.trace(self + " was triggered by " + actronaut + ", which is a " + actronaut.getBaseObject()) + ; see if this is the right actor and make sure it isn't a corpse + if actronaut.getBaseObject() == NPCtoDisable && (actronaut as actor).isDead() == false + if myQuest != NONE + ; check conditions + if (preRequisiteStage != -1 && myQuest.getStageDone(preRequisiteStage) == true) || (preRequisiteStage == -1) + myQuest.setStage(stageToSet) + ; fade out the actor we care about + actronaut.disable(true) + ; change states and let the trigger commit suicide + gotoState("finished") + endif + else + ; myQuest must == NONE, so just roll with it as all other data is now irrelevant + actronaut.disable(true) + gotoState("finished") + endif + endif + endEVENT +endSTATE +;================================================================= +STATE finished + EVENT onBeginState() + self.disable() + self.delete() + endEVENT +endSTATE diff --git a/source/scripts/defaultfireweaponscript.psc b/source/scripts/defaultfireweaponscript.psc new file mode 100644 index 00000000..cdccf6d3 --- /dev/null +++ b/source/scripts/defaultfireweaponscript.psc @@ -0,0 +1,142 @@ +Scriptname defaultFireWeaponScript extends ObjectReference +{Script for firing projectiles from FireWeaponMarker +-The default setting is to fire whatever weapon/ammo you choose infintely, every 4-6 seconds, if the marker is enabled +-If you just want it to fire once then set MinWaitTime to 0.0, MaxWaitTime to 0.1, and TimesFired to 1} + +import utility +import weapon +import debug + + +;--------------------------- +;--Hidden Properties +;--------------------------- +int Property TimesFired Auto Hidden +{How many times i've already fired} + +bool Property Looping auto hidden +{If true I should keep firing} + +float Property WaitTimer Auto hidden +{Rand wait time generated based on the Min and Max wait times} + + +;--------------------------- +;--Editable Properties +;--------------------------- +int Property TimesToFire = -1 Auto +{Maximum number of times you want this to fire once it's enabled. (-1 = until disabled)} + +float Property MaxWaitTime = 6.0 auto +{Maximum wait between refire, Default = 6.0} + +float Property MinWaitTime = 4.0 auto +{Minimum wait between refire, Default = 4.0} + +weapon Property WeaponType Auto +{Type of weapon you want to fire, (ie. "HuntingBow")} + +ammo Property Ammotype Auto +{Type of ammo you would like to fire, (ie. "IronArrow")} + +quest Property myQuest Auto +{Quest you want to check the stage of} + +int Property StageToStartFire = -1 Auto +{Stage of myQuest you want to start firing at} + +int Property StageToStopFire = -1 Auto +{Stage of myQuest you want to stop firing at (-1 = until disabled)} + + + +Event OnLoad() + ; I'm loaded, or have been enabled, so start the fire loop + Looping = TRUE + GoToState("FireLoop") +endEVENT + +Event OnUnload() + ; I've been unloaded, or disabled. Stop firing + Looping = FALSE + GoToState("Waiting") +endEVENT + + +auto state Waiting + ; The state I hang out in while I'm waiting for something to happen. +endstate + + +state FireLoop + EVENT OnBeginState() + + While(Looping) + ;trace(self + "I'm looping...") + ; Set up what our next wait time will be before firing + waitTimer = randomFloat(MinWaitTime, MaxWaitTime) + + wait(waitTimer) + + if (myQuest) + ; There is a quest set, lets see if it's running + if (myQuest.IsRunning()) + ; There is a quest running, lets see if we should be firing + if (myQuest.GetStage() >= StageToStopFire) + ;trace(self + " The done stage has been hit. No longer going to fire. Also dropping out of loop") + ; The quest is at the stop firing stage, so don't fire + Looping = False + elseif (myQuest.GetStage() >= StageToStartFire) + ;trace(self + " The correct stage is set, I'm going to fire.") + ; The quest isn't at the stop firing stage yet, but is at the firing stage, so see if we are enabled + if (self as ObjectReference).IsEnabled() + ; We're enabled, start firing + ;trace(self + " is firing.") + WeaponType.fire( self as objectReference, Ammotype) ;I'm enabled so fire. + TimesFired += 1 + else + ; We're not enabled, so don't fire + endif + if (TimesToFire != -1) + ; There is a fire limit set, check to see if we've reached it + ;trace(self + " has a firing limit of " + TimesToFire + " and has fired " + TimesFired + " so far.") + if (TimesFired == TimesToFire) + ; We've reached our fire limit, stop firing + ;trace(self + " has reached it's firing limit of " + TimesToFire + ". Stopping fire and while loop.") + Looping = False + endif + endif + else + ;trace(self + " Has a quest but the start/stop stages aren't set yet.") + endif + else + ; The quest isn't running, wait for a bit then check again + wait(8) + endif + + else + ; There's no quest set so I'm just going to continue without worrying about quests/stages + if (self as ObjectReference).IsEnabled() + ; I'm enabled, so I'm going to fire + WeaponType.fire( self as objectReference, Ammotype) + TimesFired += 1 + else + ; I'm not enabled, so I'm going to stop firing + Looping = False + endif + if (TimesToFire != -1) + ; I have a firing limit set, lets see if I've reached it + if (TimesFired == TimesToFire) + ; I've reached my limit, stop firing + Looping = False + endif + endif + endif + + endWhile + + ; I'm no longer in the fireloop, time to wait + goToState("Waiting") + endEvent +endstate + diff --git a/source/scripts/defaultforceevaluatepackagetrigger.psc b/source/scripts/defaultforceevaluatepackagetrigger.psc new file mode 100644 index 00000000..5ba7b9f2 --- /dev/null +++ b/source/scripts/defaultforceevaluatepackagetrigger.psc @@ -0,0 +1,15 @@ +Scriptname defaultForceEvaluatePackageTrigger extends ObjectReference +{Forces the actor and/or alias to evaluate its package after a brief delay.} + +ObjectReference property actorToForce Auto +ReferenceAlias property aliasToForce Auto + +EVENT OnTriggerEnter(objectReference actronaut) + Utility.Wait(0.1) + if (actorToForce != None) + (actorToForce As Actor).EvaluatePackage() + EndIf + if (aliasToForce != None) + aliasToForce.GetActorReference().EvaluatePackage() + EndIf +endEVENT diff --git a/source/scripts/defaultghostscript.psc b/source/scripts/defaultghostscript.psc new file mode 100644 index 00000000..eee43d18 --- /dev/null +++ b/source/scripts/defaultghostscript.psc @@ -0,0 +1,165 @@ +Scriptname defaultGhostScript extends Actor + +EFFECTSHADER PROPERTY pGhostFXShader AUTO +FORMLIST PROPERTY pDefaultGhostWeaponFlickerList AUTO +CONTAINER PROPERTY pDefaultGhostCorpse AUTO +EXPLOSION PROPERTY pdefaultGhostDeathExplosion AUTO +LEVELEDITEM PROPERTY pdefaultGhostLeveledList AUTO + +BOOL PROPERTY bdefaultLoot=FALSE AUTO +{mark true if you want the default ghost loot and not the NPCs} + +BOOL PROPERTY bflicker=FALSE AUTO +{don't use this yet} + +SPELL PROPERTY pGhostAbilityNew AUTO +SPELL PROPERTY pGhostResistsAbility AUTO + +; //any perks you want to add +PERK PROPERTY pGhostHalfDamagePerk AUTO + +BOOL PROPERTY bFade=FALSE AUTO +{makes the ghost fade out instead of explode} + +; //make sure only one flash is active +BOOL bFlash=FALSE + +; //the person who caused the ghost to flash +ACTOR target + +; ////////// +; //LOOT PILE VARIABLES +; ////////// + +; ////////// +; //ASH PILE VARIABLES +; ////////// +float property fDelay = 0.75 auto +{time to wait before Spawning Ash Pile} +float property fDelayEnd = 1.65 auto +{time to wait before Removing Base Actor} +float property ShaderDuration = 0.00 auto +{Duration of Effect Shader.} +Activator property pDefaultAshPileGhost auto +{The object we use as a pile.} +Bool property bSetAlphaZero = True auto +{The Effect Shader we want.} +FormList Property pDisintegrationMainImmunityList auto +{If the target is in this list, they will not be disintegrated.} +EFFECTSHADER PROPERTY pGhostDeathFXShader AUTO +{the shader to play while dying} + +race VictimRace +bool TargetIsImmune = True + +; /////////// +; //ONLOAD +; /////////// +EVENT onLoad() + + ; // add on the abilities + SELF.addSpell(pGhostAbilityNew) + SELF.addSpell(pGhostResistsAbility) + + ; // for some reason this makes ghostFlash work better + IF(bFlicker) + ghostFlash(1) + ENDIF + +ENDEVENT + +; ///////// +; //ONHIT: When the ghost is hit, if the player isnt using the proper weapon, have them fade +; ///////// +EVENT onHIT(OBJECTREFERENCE akAggressor, FORM akSource, Projectile akProjectile, BOOL abPowerAttack, BOOL abSneakAttack, BOOL abBashAttack, BOOL abHitBlocked) + + ; //if we're supposed to flicker and we're hit by a weapon without turn and we're not blocked, flash + IF(bflicker && !pDefaultGhostWeaponFlickerList.hasForm(akSource) && !abHitBlocked && !bFlash) + bFlash = TRUE + target = akAggressor as ACTOR + ghostFlash(3) + ENDIF + +ENDEVENT + +; ///////// +; //GHOSTFLASH: play this to flash the ghost when hit or attacking +; // +; //float time: the amount of time to be invincible +; ///////// +FUNCTION ghostFlash(FLOAT time) + + ; //stop the effect to keep the particles + pGhostFXShader.stop(SELF) + SELF.setGhost() + + ; //be invincible for x seconds + utility.wait(time) + + ; //return the ghost to normal + SELF.setGhost(FALSE) + SELF.setAlpha(0.3) + pGhostFXShader.play(SELF) + + bFlash = FALSE + +ENDFUNCTION + +; ///////// +; //ONDYING: On dying play an explosion to mask the ghost vanishing and being replaced by his corpse +; ///////// +EVENT onDYING(ACTOR killer) + + IF(bFade) + SELF.blockActivation(TRUE) + disable(1) + ELSE + + ; //check to see if the target is in the immunity list + IF(pDisintegrationMainImmunityList == none) + TargetIsImmune = False + ELSE + ActorBase VictimBase = SELF.GetBaseObject() as ActorBase + VictimRace = VictimBase.GetRace() + + IF(pDisintegrationMainImmunityList.hasform(VictimRace) || pDisintegrationMainImmunityList.hasform(VictimBase)) + TargetIsImmune = True + ELSE + TargetIsImmune = False + ENDIF + ENDIF + + ; //if the target is not immune, disintegrate them + IF(TargetIsImmune == False) +; debug.trace("victim just died") + + SELF.SetCriticalStage(SELF.CritStage_DisintegrateStart) + + IF(pGhostDeathFXShader != none) + pGhostDeathFXShader.play(SELF,ShaderDuration) + ENDIF + + SELF.SetAlpha (0.0,True) + + ; //attach the ash pile + SELF.AttachAshPile(pDefaultAshPileGhost) + + IF(bdefaultLoot) + SELF.RemoveAllItems() + SELF.addItem(pdefaultGhostLeveledList) + ENDIF + + + utility.wait(fDelayEnd) + IF(pGhostDeathFXShader != none) + pGhostDeathFXShader.stop(SELF) + ENDIF + IF(bSetAlphaZero == True) + SELF.SetAlpha (0.0,True) + ENDIF + SELF.SetCriticalStage(SELF.CritStage_DisintegrateEnd) + ENDIF + + ENDIF + +ENDEVENT diff --git a/source/scripts/defaultifaliveplaysoundscript.psc b/source/scripts/defaultifaliveplaysoundscript.psc new file mode 100644 index 00000000..1446a10d --- /dev/null +++ b/source/scripts/defaultifaliveplaysoundscript.psc @@ -0,0 +1,35 @@ +Scriptname defaultIfAlivePlaySoundScript extends ObjectReference +{If actor is alive, play this sound at this marker on trigger enter} + +import debug + +Actor property myActor auto +{the actor to check whether dead or alive} + +Sound property mySound auto +{the sound to play} + +ObjectReference property mySoundOrigin auto +{the reference to play the sound from} + +;************************************ + +auto State waiting + EVENT onTriggerEnter(ObjectReference triggerRef) + Actor actorRef = triggerRef as Actor + if(actorRef == game.GetPlayer()) + gotoState("done") + if(myActor.isDead()==false) + mySound.play(mySoundOrigin) + endif + endif + ENDEVENT +endState + +;************************************ + +State done + ;do nothing +endState + +;************************************ \ No newline at end of file diff --git a/source/scripts/defaultimodareatrig.psc b/source/scripts/defaultimodareatrig.psc new file mode 100644 index 00000000..87a024d8 --- /dev/null +++ b/source/scripts/defaultimodareatrig.psc @@ -0,0 +1,21 @@ +scriptName defaultImodAreaTrig extends objectReference + +ImageSpaceModifier property iMod auto +{the imod to apply. Default darkens & desaturates} +;ImageSpaceModifier property intro auto +;ImageSpaceModifier property outro auto + + +EVENT onTriggerEnter(objectReference actronaut) + if actronaut == game.getPlayer() + ;intro.apply() + imod.applyCrossFade(2.0) + endif +endEVENT + +EVENT onTriggerLeave(objectReference actronaut) + if actronaut == game.getPlayer() + ;outro.apply() + ;imod.RemoveCrossFade() + endif +endEVENT diff --git a/source/scripts/defaultlinkrefstartcombatplayer.psc b/source/scripts/defaultlinkrefstartcombatplayer.psc new file mode 100644 index 00000000..dec8d822 --- /dev/null +++ b/source/scripts/defaultlinkrefstartcombatplayer.psc @@ -0,0 +1,29 @@ +scriptName defaultLinkRefStartCombatPlayer extends objectReference +{trigger that causes linked ref to attack player (or other actor if property is over-ridden on local ref} + +objectReference property victim auto +{by default, the player} +actor property attacker auto hidden +bool property makeAggressive = false auto + +auto STATE waiting + EVENT onTriggerEnter(objectReference actronaut) + attacker = self.getLinkedRef() as actor + + if attacker.isDead() == true || attacker.isinCombat() == true + ; don't do a thing if the attacker is dead or already in combat + + elseif actronaut as actor == victim + attacker.startCombat(victim as actor) + if makeAggressive == true + attacker.setActorValue("aggression", 3) + endif + gotoState("inactive") + self.delete() + endif + endEVENT +endSTATE + +STATE inactive + ; nothing happens here. +endSTATE diff --git a/source/scripts/defaultonenter.psc b/source/scripts/defaultonenter.psc new file mode 100644 index 00000000..e796f234 --- /dev/null +++ b/source/scripts/defaultonenter.psc @@ -0,0 +1,150 @@ +Scriptname defaultOnEnter extends ObjectReference Conditional +{script to test if one or more actors are in a trigger} + +import game +import debug + +ActorBase property TriggerActor1 auto +{actor that trigger is looking for - all non-empty trigger actors need to be in trigger in order for IsTriggerReady to be true + Update OnInit when adding new trigger properties!} + +ActorBase property TriggerActor2 auto +{ref that trigger is looking for - all non-empty trigger actors need to be in trigger in order for stage to be set + Update OnInit when adding new trigger properties!} + +ActorBase property TriggerActor3 auto +{ref that trigger is looking for - all non-empty trigger actors need to be in trigger in order for stage to be set + Update OnInit when adding new trigger properties!} + +ActorBase property TriggerActor4 auto +{ref that trigger is looking for - all non-empty trigger actors need to be in trigger in order for stage to be set + Update OnInit when adding new trigger properties!} + +ReferenceAlias property TriggerAlias1 auto +{ref ALIAS that trigger is looking for - all non-empty triggerRefs need to be in trigger in order for stage to be set + Update OnInit when adding new trigger properties!} + + +; etc. - add more as needed +bool property disableWhenDone = false auto +{ disable myself after I've been triggered. Defaults to false } + + +;total targets currently in the trigger +int targetCountCurrent + +;how many targets are we looking for? When targetCountCurrent reaches this, we trigger +int targetCountTotal + +Event OnInit() + ; count my non-empty trigger properties + if TriggerActor1 + targetCountTotal = targetCountTotal + 1 + endif + if TriggerActor2 + targetCountTotal = targetCountTotal + 1 + endif + if TriggerActor3 + targetCountTotal = targetCountTotal + 1 + endif + if TriggerActor4 + targetCountTotal = targetCountTotal + 1 + endif + if TriggerAlias1 + targetCountTotal = targetCountTotal + 1 + endif +endEvent + + +auto STATE waiting + + EVENT onTriggerEnter(objectReference triggerRef) + if CheckTriggerRef(triggerRef) + ; increase ref count + modTargetCount(1) + ; if all target refs are in the trigger, done + if bAllTargetsInTrigger + TriggerMe() + endif + endif + endEVENT + + EVENT OnTriggerLeave(objectReference triggerRef) + if CheckTriggerRef(triggerRef) + ; decrease ref count + modTargetCount(-1) + endif + endEvent + +endSTATE + +STATE hasBeenTriggered + ; this is an empty state. +endSTATE + +function modTargetCount(int modValue) + targetCountCurrent = targetCountCurrent + modValue + ; failsafe - don't go below 0 + if targetCountCurrent < 0 + targetCountCurrent = 0 + endif + ; update bAllTargetsInTrigger + if targetCountCurrent >= targetCountTotal + bAllTargetsInTrigger = true + else + bAllTargetsInTrigger = false + endif +endFunction + +int function GetCurrentTargetCount() + return targetCountCurrent +endFunction + +int function GetTotalTargetCount() + return targetCountTotal +endFunction + +bool function IsTriggerReady() + return ( GetCurrentTargetCount() >= GetTotalTargetCount() ) +endfunction + +bool function CheckTriggerRef(objectReference triggerRef) +; debug.trace(self + "CheckTriggerRef for " + triggerRef) + bool bSuccess = false + + if triggerRef + Actor triggerActor = triggerRef as Actor + + if triggerActor + ; we have an actor, check if it matches any of our trigger actors + ActorBase triggerActorBase = triggerActor.GetActorBase() +; debug.trace(self + "CheckTriggerRef for " + triggerRef + ": actorbase=" + triggerActorBase) + if triggerActorBase == TriggerActor1 || triggerActorBase == TriggerActor2 || triggerActorBase == TriggerActor3 || triggerActorBase == TriggerActor4 +; debug.trace(self + "CheckTriggerRef for " + triggerRef + ": MATCHED") + bSuccess = true + else +; debug.trace(self + "CheckTriggerRef for " + triggerRef + ": failed to match " + TriggerActor1 + ", " + TriggerActor2 + ", " + TriggerActor3 + ", " + TriggerActor4) + endif + endif + ; if we haven't already found something, check aliases + if !bSuccess + if (TriggerAlias1 && triggerRef == TriggerAlias1.GetRef()) + bSuccess = true + endif + endif + endif + + return bSuccess +endFunction + +; what happens when all my targets are in the trigger? +; override on subclass to change behavior +function TriggerMe() + if disableWhenDone + gotoState("hasBeenTriggered") + Disable() + endif +endFunction + +bool Property bAllTargetsInTrigger = false Auto conditional +{true when all targets are in trigger} \ No newline at end of file diff --git a/source/scripts/defaultpillarpuzzlelever.psc b/source/scripts/defaultpillarpuzzlelever.psc new file mode 100644 index 00000000..86079750 --- /dev/null +++ b/source/scripts/defaultpillarpuzzlelever.psc @@ -0,0 +1,88 @@ +scriptName defaultPillarPuzzleLever extends ObjectReference +{ +- This script lives on the lever that controls each of the pillars +- Each pillar should have its linkedRef point to the lever that this script is on +} + + +import debug +import utility + +bool property puzzleSolved auto hidden +bool property doorOpened auto hidden +int property numPillarsSolved auto hidden + +objectReference property puzzleDoorActivator auto +{The Parent Activator Dummy Ref for Door} + +int property pillarCount auto +{Number of Puzzle Pillars} + +objectReference property refActOnSuccess01 auto +{This ref is activated when puzzle is solved and lever is pulled} + +objectReference property refActOnFailure01 auto +{This ref is activated when puzzle is not solved and lever is pulled} + +objectReference property refActOnFailure02 auto +{This ref is activated when puzzle is not solved and lever is pulled} + +objectReference property refActOnFailure03 auto +{This ref is activated when puzzle is not solved and lever is pulled} + +objectReference property refActOnFailure04 auto +{This ref is activated when puzzle is not solved and lever is pulled} + +;***************************************** + +Function doorOrDarts() + ;if the puzzle is solved, activate the refActonSuccess01 + ;else if the puzzle is not solved, activate the refActOnFailures (the dart traps + ;in the case of BleakFallsBarrow01) + ;wait(6) + if (numPillarsSolved == PillarCount) + puzzleSolved = true + refActOnSuccess01.activate(puzzleDoorActivator) + int openState = refActOnSuccess01.getOpenState() + if (openState == 1 || openState == 2) + doorOpened = true + else + doorOpened = false + endif + else + puzzleSolved = false + refActOnFailure01.activate (self as objectReference) + refActOnFailure02.activate (self as objectReference) + refActOnFailure03.activate (self as objectReference) + refActOnFailure04.activate (self as objectReference) + endif +endFunction + +;***************************************** + +Auto STATE Waiting + EVENT onActivate (objectReference triggerRef) + Actor actorRef = triggerRef as Actor + gotoState("busy") + if(actorRef==game.GetPlayer()) + ;notification("just activated lever") + doorOrDarts() + else + ;wait(3) + doorOrDarts() + endif + gotoState("Waiting") + endEVENT +endState + + +;***************************************** + +STATE busy + ; This is the state when I'm busy animating + EVENT onActivate (objectReference triggerRef) + ;do nothing + endEVENT +endState + +;***************************************** \ No newline at end of file diff --git a/source/scripts/defaultpillarpuzzlelevernofurn.psc b/source/scripts/defaultpillarpuzzlelevernofurn.psc new file mode 100644 index 00000000..77e61bd1 --- /dev/null +++ b/source/scripts/defaultpillarpuzzlelevernofurn.psc @@ -0,0 +1,95 @@ +scriptName defaultPillarPuzzleLeverNoFurn extends ObjectReference +{ +- This script lives on the lever that controls each of the pillars +- Each pillar should have its linkedRef point to the lever that this script is on +} + + +import debug +import utility + +bool property puzzleSolved auto hidden +bool property doorOpened auto hidden +int property numPillarsSolved auto hidden + +objectReference property puzzleDoorActivator auto +{The Parent Activator Dummy Ref for Door} + +int property pillarCount auto +{Number of Puzzle Pillars} + +objectReference property refActOnSuccess01 auto +{This ref is activated when puzzle is solved and lever is pulled} + +objectReference property refActOnFailure01 auto +{This ref is activated when puzzle is not solved and lever is pulled} + +objectReference property refActOnFailure02 auto +{This ref is activated when puzzle is not solved and lever is pulled} + +objectReference property refActOnFailure03 auto +{This ref is activated when puzzle is not solved and lever is pulled} + +objectReference property refActOnFailure04 auto +{This ref is activated when puzzle is not solved and lever is pulled} + +;***************************************** + +Function doorOrDarts() + ;if the puzzle is solved, activate the refActonSuccess01 + ;else if the puzzle is not solved, activate the refActOnFailures (the dart traps + ;in the case of BleakFallsBarrow01) + ;wait(6) + if (numPillarsSolved == PillarCount) + puzzleSolved = true + refActOnSuccess01.activate(puzzleDoorActivator) + int openState = refActOnSuccess01.getOpenState() + if (openState == 1 || openState == 2) + doorOpened = true + else + doorOpened = false + endif + else + puzzleSolved = false + refActOnFailure01.activate (self as objectReference) + refActOnFailure02.activate (self as objectReference) + refActOnFailure03.activate (self as objectReference) + refActOnFailure04.activate (self as objectReference) + endif +endFunction + +;***************************************** + +Auto STATE pulledPosition + EVENT onActivate (objectReference triggerRef) + Actor actorRef = triggerRef as Actor + gotoState("busy") + ;notification("just activated lever") + doorOrDarts() + playAnimationandWait("FullPush","FullPushedUp") + gotoState("pushedPosition") + endEVENT +endState + +;***************************************** + +STATE pushedPosition + EVENT onActivate (objectReference triggerRef) + gotoState ("busy") + ;notification("just activated lever") + doorOrDarts() + playAnimationandWait("FullPull","FullPulledDown") + gotoState("pulledPosition") + endEVENT +endState + +;***************************************** + +STATE busy + ; This is the state when I'm busy animating + EVENT onActivate (objectReference triggerRef) + ;do nothing + endEVENT +endState + +;***************************************** \ No newline at end of file diff --git a/source/scripts/defaultpillarpuzzlepullbarnofurn.psc b/source/scripts/defaultpillarpuzzlepullbarnofurn.psc new file mode 100644 index 00000000..74ea34e5 --- /dev/null +++ b/source/scripts/defaultpillarpuzzlepullbarnofurn.psc @@ -0,0 +1,83 @@ +scriptName defaultPillarPuzzlePullBarNoFurn extends ObjectReference +{ +- This script lives on the lever that controls each of the pillars +- Each pillar should have its linkedRef point to the lever that this script is on +} + + +import debug +import utility + +bool property puzzleSolved auto hidden +bool property doorOpened auto hidden +int property numPillarsSolved auto hidden + +objectReference property puzzleDoorActivator auto +{The Parent Activator Dummy Ref for Door} + +int property pillarCount auto +{Number of Puzzle Pillars} + +objectReference property refActOnSuccess01 auto +{This ref is activated when puzzle is solved and lever is pulled} + +objectReference property refActOnFailure01 auto +{This ref is activated when puzzle is not solved and lever is pulled} + +objectReference property refActOnFailure02 auto +{This ref is activated when puzzle is not solved and lever is pulled} + +objectReference property refActOnFailure03 auto +{This ref is activated when puzzle is not solved and lever is pulled} + +objectReference property refActOnFailure04 auto +{This ref is activated when puzzle is not solved and lever is pulled} + +;***************************************** + +Function doorOrDarts() + ;if the puzzle is solved, activate the refActonSuccess01 + ;else if the puzzle is not solved, activate the refActOnFailures (the dart traps + ;in the case of BleakFallsBarrow01) + ;wait(6) + if (numPillarsSolved == PillarCount) + puzzleSolved = true + refActOnSuccess01.activate(puzzleDoorActivator) + int openState = refActOnSuccess01.getOpenState() + if (openState == 1 || openState == 2) + doorOpened = true + else + doorOpened = false + endif + else + puzzleSolved = false + refActOnFailure01.activate (self as objectReference) + refActOnFailure02.activate (self as objectReference) + refActOnFailure03.activate (self as objectReference) + refActOnFailure04.activate (self as objectReference) + endif +endFunction + +;***************************************** + +Auto STATE Waiting + EVENT onActivate (objectReference triggerRef) + Actor actorRef = triggerRef as Actor + gotoState("busy") + ;notification("just activated lever") + doorOrDarts() + playAnimationandWait("Pull","Reset") + gotoState("Waiting") + endEVENT +endState + +;***************************************** + +STATE busy + ; This is the state when I'm busy animating + EVENT onActivate (objectReference triggerRef) + ;do nothing + endEVENT +endState + +;***************************************** \ No newline at end of file diff --git a/source/scripts/defaultplayerenabledisablelinkedref.psc b/source/scripts/defaultplayerenabledisablelinkedref.psc new file mode 100644 index 00000000..c70ef83a --- /dev/null +++ b/source/scripts/defaultplayerenabledisablelinkedref.psc @@ -0,0 +1,48 @@ +scriptName defaultPlayerEnableDisableLinkedRef extends ObjectReference +{ +- This script enables or disables linked ref based on which type user defines in properties. On Activator, or OnTriggerEnter, whichever is first. +- This script is for player trigger/activator only +- This script only fires once +} + +int property TriggerType auto +{ +0 (default) - enables linked ref +1 - disables linked ref +} + +ObjectReference myLinkedRef + +auto STATE Waiting + + Event onTriggerEnter(ObjectReference triggerRef) +; Debug.Trace("Toggling: " + myLinkedRef) + myLinkedRef = GetLinkedRef() as ObjectReference + if (triggerRef == (Game.GetPlayer() as ObjectReference)) + if (TriggerType == 0) + myLinkedRef.enable() + elseif (TriggerType == 1) + myLinkedRef.disable() + endif + GoToState("Done") + endif + endEvent + + Event onActivate(ObjectReference triggerRef) +; Debug.Trace("Toggling: " + myLinkedRef) + myLinkedRef = GetLinkedRef() as ObjectReference + if (triggerRef == (Game.GetPlayer() as ObjectReference)) + if (TriggerType == 0) + myLinkedRef.enable() + elseif (TriggerType == 1) + myLinkedRef.disable() + endif + GoToState("Done") + endif + endEvent + +endSTATE + +STATE Done + ;Do Nothing +endSTATE diff --git a/source/scripts/defaultplaysoundatlinkscript.psc b/source/scripts/defaultplaysoundatlinkscript.psc new file mode 100644 index 00000000..e45ad799 --- /dev/null +++ b/source/scripts/defaultplaysoundatlinkscript.psc @@ -0,0 +1,37 @@ +Scriptname DefaultPlaySoundAtLinkSCRIPT extends ObjectReference +{ +Plays the sound (property) and this trigger's linked ref. +-This script only fires once then disables itself. +-Probably currently only supports one shot sounds. +-May want to add options later to start and stop looping sounds. +} + +Sound Property SelectedSound Auto +{ +Pick the Sound that you want to be played. +} + +float Property Volume Auto +{ +The volume you'd like the sound to play at (Between 0 and 1, (DEFAULT = 1)) +} + +bool Property PlayerOnly = TRUE auto +{ +Does this only trigger for the player? (DEFAULT = TRUE) +} + +ObjectReference myLinkedRef + +Event onTriggerEnter(ObjectReference triggerRef) + + if (triggerRef == Game.GetPlayer()) || (!PlayerOnly) + myLinkedRef = GetLinkedRef() as ObjectReference + + int soundInstance = SelectedSound.play(myLinkedRef) + Sound.SetInstanceVolume(soundInstance, Volume) + + self.disable() + endif + +endEvent diff --git a/source/scripts/defaultprisonerdoorscript.psc b/source/scripts/defaultprisonerdoorscript.psc new file mode 100644 index 00000000..62b33b1b --- /dev/null +++ b/source/scripts/defaultprisonerdoorscript.psc @@ -0,0 +1,101 @@ +Scriptname defaultPrisonerDoorSCRIPT extends ObjectReference +{Default script on a door, that's linked to a prisoner, to handle his factions.} + + +import game +import utility +import debug + +Faction Property dunPrisonerFaction Auto +ObjectReference Property Prisoner01 Auto +ObjectReference Property Prisoner02 Auto +ObjectReference Property Prisoner03 Auto +ObjectReference Property Prisoner04 Auto +ObjectReference Property Prisoner05 Auto +ObjectReference Property Prisoner06 Auto + +ObjectReference Property PrisonerLink Auto Hidden +bool Property AlreadyLoaded Auto Hidden + + + +EVENT OnLoad() + if AlreadyLoaded == FALSE + if Prisoner01 + (Prisoner01 as Actor).AddToFaction(dunPrisonerFaction) + endif + if Prisoner02 + (Prisoner02 as Actor).AddToFaction(dunPrisonerFaction) + endif + if Prisoner03 + (Prisoner03 as Actor).AddToFaction(dunPrisonerFaction) + endif + if Prisoner04 + (Prisoner04 as Actor).AddToFaction(dunPrisonerFaction) + endif + if Prisoner05 + (Prisoner05 as Actor).AddToFaction(dunPrisonerFaction) + endif + if Prisoner06 + (Prisoner06 as Actor).AddToFaction(dunPrisonerFaction) + endif + + PrisonerLink = GetLinkedRef() + if PrisonerLink + (PrisonerLink as Actor).AddToFaction(dunPrisonerFaction) + endif + + endif + AlreadyLoaded = TRUE +EndEVENT + + +Auto STATE WaitingToBeOpened + + EVENT OnOpen (ObjectReference triggerRef) + if Prisoner01 + (Prisoner01 as Actor).RemoveFromFaction(dunPrisonerFaction) + Utility.Wait(0.1) + (Prisoner01 as Actor).EvaluatePackage() + endif + if Prisoner02 + (Prisoner02 as Actor).RemoveFromFaction(dunPrisonerFaction) + Utility.Wait(0.1) + (Prisoner02 as Actor).EvaluatePackage() + endif + if Prisoner03 + (Prisoner03 as Actor).RemoveFromFaction(dunPrisonerFaction) + Utility.Wait(0.1) + (Prisoner03 as Actor).EvaluatePackage() + endif + if Prisoner04 + (Prisoner04 as Actor).RemoveFromFaction(dunPrisonerFaction) + Utility.Wait(0.1) + (Prisoner04 as Actor).EvaluatePackage() + endif + if Prisoner05 + (Prisoner05 as Actor).RemoveFromFaction(dunPrisonerFaction) + Utility.Wait(0.1) + (Prisoner05 as Actor).EvaluatePackage() + endif + if Prisoner06 + (Prisoner06 as Actor).RemoveFromFaction(dunPrisonerFaction) + Utility.Wait(0.1) + (Prisoner06 as Actor).EvaluatePackage() + endif + + if PrisonerLink + (PrisonerLink as Actor).RemoveFromFaction(dunPrisonerFaction) + Utility.Wait(0.1) + (PrisonerLink as Actor).EvaluatePackage() + endif + + GoToState("AlreadyOpened") + EndEVENT + +endSTATE + +STATE AlreadyOpened + ;do nothing +EndSTATE + diff --git a/source/scripts/defaultpuzzlepillarnofurn.psc b/source/scripts/defaultpuzzlepillarnofurn.psc new file mode 100644 index 00000000..8590ca4d --- /dev/null +++ b/source/scripts/defaultpuzzlepillarnofurn.psc @@ -0,0 +1,114 @@ +scriptName defaultPuzzlePillarNoFurn extends ObjectReference +{ +- User can use properties to set the pillar's initial state and solve state +- The script first checks to see if the initial state is the same as the solve state +- When the pillar is activated, the pillar rotates to a new position and then checks to see if its solved +- If pillar is solved, the script increments neccessary vars in the defaultPillarPuzzleLever.psc +- Each pillar needs to have its linkedRef point to the lever where the defaultPillarPuzzleLever.psc lives +} + + +import debug +import utility + +bool pillarSolved +bool doOnce + +defaultPillarPuzzleLeverNoFurn myLinkedRef + +int property initialState auto +{ +This is the position the pillar starts out in. +1 = Position 1 (eagle) +2 = Position 2 (snake) +3 = Position 3 (whale) +Position 1,2,3 refer to the havok animations +} + +int property solveState auto +{ +This is the position the pillar needs to be in to be considered solved. +1 = Position 1 (eagle) +2 = Position 2 (snake) +3 = Position 3 (whale) +Position 1,2,3 refer to the havok animations +} + +Event OnCellLoad() + myLinkedRef = GetLinkedRef() as defaultPillarPuzzleLeverNoFurn + + ;account for case where initialState and solveState are equal in the beginning + if(!doOnce) + if (initialState == solveState) + myLinkedRef.numPillarsSolved = myLinkedRef.numPillarsSolved + 1 + pillarSolved = true + endif + + ;now move the pillar into initialState + if (initialState == 1) + ;no animation + gotoState("position01") + elseif (initialState == 2) + playAnimation("StartState02") + gotoState("position02") + elseif (initialState == 3) + playAnimation("StartState03") + gotoState("position03") + endif + + doOnce = true + endif +endEvent + +; Makes the pillar rotate to the next state and checks whether it is 'solved' as a result +FUNCTION RotatePillarToState(int stateNumber, int animEventNumber) + gotoState ("busy") + if (solveState == stateNumber) + ;trace(self + " pillar solved!") + myLinkedRef.numPillarsSolved = myLinkedRef.numPillarsSolved + 1 + pillarSolved = true + elseif (pillarSolved == True) + ;if the puzzle is solved and the door is open, then activate the linkedRef (lever) + ;and set the puzzleSolved to false as well as the doorOpened + if (myLinkedRef.puzzleSolved == true && myLinkedRef.doorOpened == 1) + myLinkedRef.refActOnSuccess01.activate (myLinkedRef.puzzleDoorActivator) + myLinkedRef.puzzleSolved = false + myLinkedRef.doorOpened = false + endif + myLinkedRef.numPillarsSolved = myLinkedRef.numPillarsSolved - 1 + pillarSolved = False + endif + playAnimationandWait("Trigger0" + animEventNumber, "Turned0" + animEventNumber) +endFUNCTION + + +STATE position01 + EVENT onActivate (objectReference triggerRef) + RotatePillarToState(2, 1) + gotoState("position02") + endEVENT +endState + + +STATE position02 + EVENT onActivate (objectReference triggerRef) + RotatePillarToState(3, 2) + gotoState("position03") + endEVENT +endState + + +STATE position03 + EVENT onActivate (objectReference triggerRef) + RotatePillarToState(1, 3) + gotoState("position01") + endEVENT +endState + + +STATE busy + ; This is the state when I'm busy animating + EVENT onActivate (objectReference triggerRef) + ;do nothing + endEVENT +endSTATE diff --git a/source/scripts/defaultpuzzlepillarpullbarnofurn.psc b/source/scripts/defaultpuzzlepillarpullbarnofurn.psc new file mode 100644 index 00000000..efdbc247 --- /dev/null +++ b/source/scripts/defaultpuzzlepillarpullbarnofurn.psc @@ -0,0 +1,114 @@ +scriptName defaultPuzzlePillarPullBarNoFurn extends ObjectReference +{ +- User can use properties to set the pillar's initial state and solve state +- The script first checks to see if the initial state is the same as the solve state +- When the pillar is activated, the pillar rotates to a new position and then checks to see if its solved +- If pillar is solved, the script increments neccessary vars in the defaultPillarPuzzleLever.psc +- Each pillar needs to have its linkedRef point to the lever where the defaultPillarPuzzleLever.psc lives +} + + +import debug +import utility + +bool pillarSolved +bool doOnce + +defaultPillarPuzzlePullBarNoFurn myLinkedRef + +int property initialState auto +{ +This is the position the pillar starts out in. +1 = Position 1 (eagle) +2 = Position 2 (snake) +3 = Position 3 (whale) +Position 1,2,3 refer to the havok animations +} + +int property solveState auto +{ +This is the position the pillar needs to be in to be considered solved. +1 = Position 1 (eagle) +2 = Position 2 (snake) +3 = Position 3 (whale) +Position 1,2,3 refer to the havok animations +} + +Event OnCellLoad() + myLinkedRef = GetLinkedRef() as defaultPillarPuzzlePullBarNoFurn + + ;account for case where initialState and solveState are equal in the beginning + if(!doOnce) + if (initialState == solveState) + myLinkedRef.numPillarsSolved = myLinkedRef.numPillarsSolved + 1 + pillarSolved = true + endif + + ;now move the pillar into initialState + if (initialState == 1) + ;no animation + gotoState("position01") + elseif (initialState == 2) + playAnimation("StartState02") + gotoState("position02") + elseif (initialState == 3) + playAnimation("StartState03") + gotoState("position03") + endif + + doOnce = true + endif +endEvent + +; Makes the pillar rotate to the next state and checks whether it is 'solved' as a result +FUNCTION RotatePillarToState(int stateNumber, int animEventNumber) + gotoState ("busy") + if (solveState == stateNumber) + ;trace(self + " pillar solved!") + myLinkedRef.numPillarsSolved = myLinkedRef.numPillarsSolved + 1 + pillarSolved = true + elseif (pillarSolved == True) + ;if the puzzle is solved and the door is open, then activate the linkedRef (lever) + ;and set the puzzleSolved to false as well as the doorOpened + if (myLinkedRef.puzzleSolved == true && myLinkedRef.doorOpened == 1) + myLinkedRef.refActOnSuccess01.activate (myLinkedRef.puzzleDoorActivator) + myLinkedRef.puzzleSolved = false + myLinkedRef.doorOpened = false + endif + myLinkedRef.numPillarsSolved = myLinkedRef.numPillarsSolved - 1 + pillarSolved = False + endif + playAnimationandWait("Trigger0" + animEventNumber, "Turned0" + animEventNumber) +endFUNCTION + + +STATE position01 + EVENT onActivate (objectReference triggerRef) + RotatePillarToState(2, 1) + gotoState("position02") + endEVENT +endState + + +STATE position02 + EVENT onActivate (objectReference triggerRef) + RotatePillarToState(3, 2) + gotoState("position03") + endEVENT +endState + + +STATE position03 + EVENT onActivate (objectReference triggerRef) + RotatePillarToState(1, 3) + gotoState("position01") + endEVENT +endState + + +STATE busy + ; This is the state when I'm busy animating + EVENT onActivate (objectReference triggerRef) + ;do nothing + endEVENT +endSTATE diff --git a/source/scripts/defaultpuzzlepillarscript.psc b/source/scripts/defaultpuzzlepillarscript.psc new file mode 100644 index 00000000..80b41982 --- /dev/null +++ b/source/scripts/defaultpuzzlepillarscript.psc @@ -0,0 +1,114 @@ +scriptName defaultPuzzlePillarScript extends ObjectReference +{ +- User can use properties to set the pillar's initial state and solve state +- The script first checks to see if the initial state is the same as the solve state +- When the pillar is activated, the pillar rotates to a new position and then checks to see if its solved +- If pillar is solved, the script increments neccessary vars in the defaultPillarPuzzleLever.psc +- Each pillar needs to have its linkedRef point to the lever where the defaultPillarPuzzleLever.psc lives +} + + +import debug +import utility + +bool pillarSolved +bool doOnce + +defaultPillarPuzzleLever myLinkedRef + +int property initialState auto +{ +This is the position the pillar starts out in. +1 = Position 1 (eagle) +2 = Position 2 (snake) +3 = Position 3 (whale) +Position 1,2,3 refer to the havok animations +} + +int property solveState auto +{ +This is the position the pillar needs to be in to be considered solved. +1 = Position 1 (eagle) +2 = Position 2 (snake) +3 = Position 3 (whale) +Position 1,2,3 refer to the havok animations +} + +Event OnCellLoad() + myLinkedRef = GetLinkedRef() as defaultPillarPuzzleLever + + ;account for case where initialState and solveState are equal in the beginning + if(!doOnce) + if (initialState == solveState) + myLinkedRef.numPillarsSolved = myLinkedRef.numPillarsSolved + 1 + pillarSolved = true + endif + + ;now move the pillar into initialState + if (initialState == 1) + ;no animation + gotoState("position01") + elseif (initialState == 2) + playAnimation("StartState02") + gotoState("position02") + elseif (initialState == 3) + playAnimation("StartState03") + gotoState("position03") + endif + + doOnce = true + endif +endEvent + +; Makes the pillar rotate to the next state and checks whether it is 'solved' as a result +FUNCTION RotatePillarToState(int stateNumber, int animEventNumber) + gotoState ("busy") + if (solveState == stateNumber) + ;trace(self + " pillar solved!") + myLinkedRef.numPillarsSolved = myLinkedRef.numPillarsSolved + 1 + pillarSolved = true + elseif (pillarSolved == True) + ;if the puzzle is solved and the door is open, then activate the linkedRef (lever) + ;and set the puzzleSolved to false as well as the doorOpened + if (myLinkedRef.puzzleSolved == true && myLinkedRef.doorOpened == 1) + myLinkedRef.refActOnSuccess01.activate (myLinkedRef.puzzleDoorActivator) + myLinkedRef.puzzleSolved = false + myLinkedRef.doorOpened = false + endif + myLinkedRef.numPillarsSolved = myLinkedRef.numPillarsSolved - 1 + pillarSolved = False + endif + playAnimationandWait("Trigger0" + animEventNumber, "Turned0" + animEventNumber) +endFUNCTION + + +STATE position01 + EVENT onActivate (objectReference triggerRef) + RotatePillarToState(2, 1) + gotoState("position02") + endEVENT +endState + + +STATE position02 + EVENT onActivate (objectReference triggerRef) + RotatePillarToState(3, 2) + gotoState("position03") + endEVENT +endState + + +STATE position03 + EVENT onActivate (objectReference triggerRef) + RotatePillarToState(1, 3) + gotoState("position01") + endEVENT +endState + + +STATE busy + ; This is the state when I'm busy animating + EVENT onActivate (objectReference triggerRef) + ;do nothing + endEVENT +endSTATE diff --git a/source/scripts/defaultsetlinkavvar.psc b/source/scripts/defaultsetlinkavvar.psc new file mode 100644 index 00000000..754efb72 --- /dev/null +++ b/source/scripts/defaultsetlinkavvar.psc @@ -0,0 +1,45 @@ +ScriptName defaultSetLinkAVvar extends objectReference +{Default script that lives on a trigger. Once triggered, it sets an actor value (property) to a value (property)} + +import game +import debug + +string property sActorVariable = "Variable01" auto +{By default, this property is set to Variable01. Set which actor variable to set as a string} + +float property fActorVariable = 1.0 auto +{By default this property is set to 1. Set what you want the actor variable to be changed to} + +objectReference property OnlyActor auto +{By default, this property is set to the player} + +bool property doOnce auto +{By default, this trigger fires only once} + +function ActivateNow(objectReference triggerRef) + ObjectReference myLink = getLinkedRef() + Actor myActor = myLink as actor + myActor.SetAV(sActorVariable, fActorVariable) + myActor.EvaluatePackage() + if doOnce == true + gotoState("allDone") + endif +endFunction + +auto State waiting + Event onTriggerEnter(objectReference triggerRef) + if !onlyActor && triggerRef == GetPlayer() + activateNow(triggerRef) + endif + + if onlyActor == triggerRef + activateNow(triggerRef) + endif + + endEvent +endState + +State allDone + ;do nothing +endState + \ No newline at end of file diff --git a/source/scripts/defaultsetmultiavtriggerscript.psc b/source/scripts/defaultsetmultiavtriggerscript.psc new file mode 100644 index 00000000..4bdbd358 --- /dev/null +++ b/source/scripts/defaultsetmultiavtriggerscript.psc @@ -0,0 +1,68 @@ +ScriptName defaultSetMultiAVTriggerScript extends ObjectReference +{Sets the specified actor value on the actor(s) to the specified value when the player enters the trigger.} + +import game +import debug + +ObjectReference property Actor1 Auto +ObjectReference property Actor2 Auto +ObjectReference property Actor3 Auto +ObjectReference property Actor4 Auto +ObjectReference property Actor5 Auto + +String property ActorValueName Auto +int property ActorValueValue Auto +bool property onlyOnce = True Auto +bool property evalPackageAfterwards = True Auto +bool property onlyPlayer = True Auto + + +auto State Waiting + Event onTriggerEnter(ObjectReference obj) + if (!onlyPlayer || obj == GetPlayer()) + if (Actor1 != None) + (Actor1 as Actor).SetAV(ActorValueName, ActorValueValue) + EndIf + if (Actor2 != None) + (Actor2 as Actor).SetAV(ActorValueName, ActorValueValue) + EndIf + if (Actor3 != None) + (Actor3 as Actor).SetAV(ActorValueName, ActorValueValue) + EndIf + if (Actor4 != None) + (Actor4 as Actor).SetAV(ActorValueName, ActorValueValue) + EndIf + if (Actor5 != None) + (Actor5 as Actor).SetAV(ActorValueName, ActorValueValue) + EndIf + + if (evalPackageAfterwards) + if (Actor1 != None) + (Actor1 as Actor).EvaluatePackage() + EndIf + if (Actor2 != None) + (Actor2 as Actor).EvaluatePackage() + EndIf + if (Actor3 != None) + (Actor3 as Actor).EvaluatePackage() + EndIf + if (Actor4 != None) + (Actor4 as Actor).EvaluatePackage() + EndIf + if (Actor5 != None) + (Actor5 as Actor).EvaluatePackage() + EndIf + EndIf + + if (onlyOnce) + GoToState("AllDone") + EndIf + EndIf + EndEvent +EndState + +State AllDone + Event OnTriggerEnter(ObjectReference obj) + ;Do nothing. + EndEvent +EndState \ No newline at end of file diff --git a/source/scripts/defaultsetstageonenter.psc b/source/scripts/defaultsetstageonenter.psc new file mode 100644 index 00000000..7512f520 --- /dev/null +++ b/source/scripts/defaultsetstageonenter.psc @@ -0,0 +1,22 @@ +Scriptname defaultSetStageOnEnter extends defaultOnEnter conditional +{sets a quest stage when the specified ref or refs are in the trigger +} + +quest property myQuest auto +{ quest to call SetStage on} + +int property stage auto +{ stage to set} + +;total targets currently in the trigger +int targetCountCurrent + +;how many targets are we looking for? When targetCountCurrent reaches this, we trigger +int targetCountTotal + +; what happens when all my targets are in the trigger? +; override on subclass to change behavior +function TriggerMe() + myQuest.setStage(stage) + parent.TriggerMe() +endFunction diff --git a/source/scripts/defaultsetstagetrigscript.psc b/source/scripts/defaultsetstagetrigscript.psc new file mode 100644 index 00000000..b0c4e9eb --- /dev/null +++ b/source/scripts/defaultsetstagetrigscript.psc @@ -0,0 +1,52 @@ +scriptname defaultSetStageTrigSCRIPT extends objectReference +{ this is a generic script for one-shot quest stage updates} + +import game +import debug + +quest property myQuest auto +{ quest to call SetStage on} + +int property stage auto +{ stage to set} + +bool property doOnce = True auto +{Set the stage only once.} + +int property prereqStageOPT = -1 auto +{ OPTIONAL: stage that must be set for this trigger to fire } + +bool property disableWhenDone = true auto +{ disable myself after I've been triggered. Defaults to true } + + +auto STATE waitingForPlayer + EVENT onTriggerEnter(objectReference triggerRef) + if triggerRef == getPlayer() as actor + ; check to see if a pre-req stage was specificed and if it's been met + if prereqStageOPT == -1 || MyQuest.getStageDone(prereqStageOPT) == 1 + ; Start the quest just in case it isn't already running. + if myQuest.isRunning() == FALSE + bool check = myQuest.start() + ; do a quick check in case the quest could not be started + if !check +; debug.trace("ERROR: "+myQuest+" not started by "+self) + endif + endif + + ; do the actual business of setting the stage we want + myQuest.setStage(stage) + if doOnce + gotoState("hasBeenTriggered") + endif + if disableWhenDone + Disable() + endif + endif + endif + endEVENT +endSTATE + +STATE hasBeenTriggered + ; this is an empty state. +endSTATE diff --git a/source/scripts/dialoguefollowerscript.psc b/source/scripts/dialoguefollowerscript.psc new file mode 100644 index 00000000..1788277e --- /dev/null +++ b/source/scripts/dialoguefollowerscript.psc @@ -0,0 +1,151 @@ +ScriptName DialogueFollowerScript extends Quest Conditional + +GlobalVariable Property pPlayerFollowerCount Auto +GlobalVariable Property pPlayerAnimalCount Auto +ReferenceAlias Property pFollowerAlias Auto +ReferenceAlias property pAnimalAlias Auto +Faction Property pDismissedFollower Auto +Faction Property pCurrentHireling Auto +Message Property FollowerDismissMessage Auto +Message Property AnimalDismissMessage Auto +Message Property FollowerDismissMessageWedding Auto +Message Property FollowerDismissMessageCompanions Auto +Message Property FollowerDismissMessageCompanionsMale Auto +Message Property FollowerDismissMessageCompanionsFemale Auto +Message Property FollowerDismissMessageWait Auto +SetHirelingRehire Property HirelingRehireScript Auto + +;Property to tell follower to say dismissal line +Int Property iFollowerDismiss Auto Conditional + +; PATCH 1.9: 77615: remove unplayable hunting bow when follower is dismissed +Weapon Property FollowerHuntingBow Auto +Ammo Property FollowerIronArrow Auto + + +Function SetFollower(ObjectReference FollowerRef) + + actor FollowerActor = FollowerRef as Actor + FollowerActor.RemoveFromFaction(pDismissedFollower) + If FollowerActor.GetRelationshipRank(Game.GetPlayer()) < 3 && FollowerActor.GetRelationshipRank(Game.GetPlayer()) >= 0 + FollowerActor.SetRelationshipRank(Game.GetPlayer(), 3) + EndIf + FollowerActor.SetPlayerTeammate() + ;FollowerActor.SetAV("Morality", 0) + pFollowerAlias.ForceRefTo(FollowerActor) + pPlayerFollowerCount.SetValue(1) + +EndFunction + +Function SetAnimal(ObjectReference AnimalRef) + + actor AnimalActor= AnimalRef as Actor + ;don't allow lockpicking + AnimalActor.SetAV("Lockpicking", 0) + AnimalActor.SetRelationshipRank(Game.GetPlayer(), 3) + AnimalActor.SetPlayerTeammate(abCanDoFavor = false) + pAnimalAlias.ForceRefTo(AnimalActor) + ;AnimalActor.AllowPCDialogue(True) + pPlayerAnimalCount.SetValue(1) + +EndFunction + +Function FollowerWait() + + actor FollowerActor = pFollowerAlias.GetActorRef() as Actor + FollowerActor.SetAv("WaitingForPlayer", 1) + ;SetObjectiveDisplayed(10, abforce = true) + ;follower will wait 3 days + pFollowerAlias.RegisterForUpdateGameTime(72) + +EndFunction + +Function AnimalWait() + + actor AnimalActor = pAnimalAlias.GetActorRef() as Actor + AnimalActor.SetAv("WaitingForPlayer", 1) + ;SetObjectiveDisplayed(20, abforce = true) + ;follower will wait 3 days + pAnimalAlias.RegisterForUpdateGameTime(72) + +EndFunction + +Function FollowerFollow() + + actor FollowerActor = pFollowerAlias.GetActorRef() as Actor + FollowerActor.SetAv("WaitingForPlayer", 0) + SetObjectiveDisplayed(10, abdisplayed = false) + +EndFunction + +Function AnimalFollow() + + actor AnimalActor = pAnimalAlias.GetActorRef() as Actor + AnimalActor.SetAv("WaitingForPlayer", 0) + SetObjectiveDisplayed(20, abdisplayed = false) + +EndFunction + +Function DismissFollower(Int iMessage = 0, Int iSayLine = 1) + + If pFollowerAlias && pFollowerAlias.GetActorRef().IsDead() == False + If iMessage == 0 + FollowerDismissMessage.Show() + ElseIf iMessage == 1 + FollowerDismissMessageWedding.Show() + ElseIf iMessage == 2 + FollowerDismissMessageCompanions.Show() + ElseIf iMessage == 3 + FollowerDismissMessageCompanionsMale.Show() + ElseIf iMessage == 4 + FollowerDismissMessageCompanionsFemale.Show() + ElseIf iMessage == 5 + FollowerDismissMessageWait.Show() + Else + ;failsafe + FollowerDismissMessage.Show() + EndIf + actor DismissedFollowerActor = pFollowerAlias.GetActorRef() as Actor + DismissedFollowerActor.StopCombatAlarm() + DismissedFollowerActor.AddToFaction(pDismissedFollower) + DismissedFollowerActor.SetPlayerTeammate(false) + DismissedFollowerActor.RemoveFromFaction(pCurrentHireling) + DismissedFollowerActor.SetAV("WaitingForPlayer", 0) + + ; PATCH 1.9: 77615: remove unplayable hunting bow when follower is dismissed + DismissedFollowerActor.RemoveItem(FollowerHuntingBow, 999, true) + DismissedFollowerActor.RemoveItem(FollowerIronArrow, 999, true) + ; END Patch 1.9 fix + + ;hireling rehire function + HirelingRehireScript.DismissHireling(DismissedFollowerActor.GetActorBase()) + If iSayLine == 1 + iFollowerDismiss = 1 + DismissedFollowerActor.EvaluatePackage() + ;Wait for follower to say line + Utility.Wait(2) + EndIf + pFollowerAlias.Clear() + iFollowerDismiss = 0 + ;don't set count to 0 if Companions have replaced follower + If iMessage == 2 + ;do nothing + Else + pPlayerFollowerCount.SetValue(0) + EndIf + EndIf + +EndFunction + +Function DismissAnimal() + + If pAnimalAlias && pAnimalAlias.GetActorRef().IsDead() == False + actor DismissedAnimalActor = pAnimalAlias.GetActorRef() as Actor + DismissedAnimalActor.SetActorValue("Variable04", 0) + ;DismissedAnimalActor.AllowPCDialogue(False) + pPlayerAnimalCount.SetValue(0) + pAnimalAlias.Clear() + AnimalDismissMessage.Show() + EndIf + +EndFunction diff --git a/source/scripts/dlc2hermaeusmorafacefxscript.psc b/source/scripts/dlc2hermaeusmorafacefxscript.psc new file mode 100644 index 00000000..968e75da --- /dev/null +++ b/source/scripts/dlc2hermaeusmorafacefxscript.psc @@ -0,0 +1,132 @@ +Scriptname DLC2HermaeusMoraFaceFXSCRIPT extends ObjectReference +{Plays all of the HM face fx when activated} + +ObjectReference Property myHMface01 Auto +ObjectReference Property myHMface02 Auto +ObjectReference Property myHMface03 Auto +ObjectReference Property myHMface04 Auto +ObjectReference Property myHMface05 Auto +ObjectReference Property myHMface06 Auto +ObjectReference Property myHMface07 Auto +ObjectReference Property myHMface08 Auto + +int iMaxCount = 10 ; max times to loop waiting for 3D to load + +auto State Waiting +; default state +endState + +State HermaeusMoraAppear + +Event OnBeginState() ;;;this bloc makes the hermaeus mora art appear + if (myHMface01) + myHMface01.disable();;this delay gets same peices out of sync + utility.wait(Utility.RandomFloat(0.2, 0.5)) + myHMface01.enable();;;;;;;;;;;; + waitfor3D(myHMface01) + myHMface01.SetAnimationVariableFloat("fToggleBlend", 1.0) + endif + if (myHMface02) + myHMface02.SetAnimationVariableFloat("fToggleBlend", 1.0) + endif + if (myHMface03) + myHMface03.disable();;this delay gets same peices out of sync + utility.wait(Utility.RandomFloat(0.2, 0.5)) + myHMface03.enable() ;;;;;; + waitfor3D(myHMface03) + myHMface03.SetAnimationVariableFloat("fToggleBlend", 1.0) + endif + if (myHMface04) + myHMface04.SetAnimationVariableFloat("fToggleBlend", 1.0) + endif + if (myHMface05) + myHMface05.disable();;this delay gets same peices out of sync + utility.wait(Utility.RandomFloat(0.2, 0.5)) + myHMface05.enable();;;;;;;;;;;; + waitfor3D(myHMface05) + myHMface05.SetAnimationVariableFloat("fToggleBlend", 1.0) + endif + if (myHMface06) + myHMface06.SetAnimationVariableFloat("fToggleBlend", 1.0) + endif + if (myHMface07) + myHMface07.disable();;this delay gets same peices out of sync + utility.wait(Utility.RandomFloat(0.2, 0.5)) + myHMface07.enable();;;;;;;;;;;; + waitfor3D(myHMface07) + myHMface07.SetAnimationVariableFloat("fToggleBlend", 1.0) + endif + if (myHMface08) + myHMface08.SetAnimationVariableFloat("fToggleBlend", 1.0) + endif +EndEvent + +endState + +State HermaeusMoraDisappear + +Event OnLoad() + ; failsafe in case HM was unloaded when changed to disappeared state + myHMface01.Disable() + myHMface02.Disable() + myHMface03.Disable() + myHMface04.Disable() + myHMface05.Disable() + myHMface06.Disable() + myHMface07.Disable() + myHMface08.Disable() +EndEvent + +Event OnBeginState() ;;;this bloc makes the hermaeus mora art disappear + if (myHMface01) + utility.wait(Utility.RandomFloat(0.2, 0.5)) + myHMface01.SetAnimationVariableFloat("fToggleBlend", 0.0) + endif + if (myHMface02) + myHMface02.SetAnimationVariableFloat("fToggleBlend", 0.0) + endif + if (myHMface03) + utility.wait(Utility.RandomFloat(0.2, 0.5)) + myHMface03.SetAnimationVariableFloat("fToggleBlend", 0.0) + endif + if (myHMface04) + myHMface04.SetAnimationVariableFloat("fToggleBlend", 0.0) + endif + if (myHMface05) + utility.wait(Utility.RandomFloat(0.2, 0.5)) + myHMface05.SetAnimationVariableFloat("fToggleBlend", 0.0) + endif + if (myHMface06) + myHMface06.SetAnimationVariableFloat("fToggleBlend", 0.0) + endif + if (myHMface07) + utility.wait(Utility.RandomFloat(0.2, 0.5)) + myHMface07.SetAnimationVariableFloat("fToggleBlend", 0.0) + endif + if (myHMface08) + myHMface08.SetAnimationVariableFloat("fToggleBlend", 0.0) + endif +EndEvent + +endState + +function ChangeState(bool bHermaeusMoraAppear = true) + if bHermaeusMoraAppear + GotoState("HermaeusMoraAppear") + else + gotoState("HermaeusMoraDisappear") + endif +endFunction + +; pass in ref, returns when 3D is loaded or maxCount reached in loop +function waitFor3D(ObjectReference myFace) +; debug.trace(self + " waiting to load " + myFace) +; debug.trace(self + " iCount=" + iCount + ", is3dloaded=" +myFace.Is3DLoaded()) + int iCount = 0 + while !myFace.Is3DLoaded() && iCount < iMaxCount + iCount = iCount + 1 + utility.wait(Utility.RandomFloat(0.2, 0.5)) +; debug.trace(self + " iCount=" + iCount + ", is3dloaded=" +myFace.Is3DLoaded()) + endwhile +endFunction + diff --git a/source/scripts/dlc2miraakcombatmagiclevelingscript.psc b/source/scripts/dlc2miraakcombatmagiclevelingscript.psc new file mode 100644 index 00000000..5b9b087f --- /dev/null +++ b/source/scripts/dlc2miraakcombatmagiclevelingscript.psc @@ -0,0 +1,100 @@ +Scriptname DLC2MiraakCombatMagicLevelingScript extends ReferenceAlias + +Int Property Stage1 = 37 Auto hidden +Int Property Stage2 = 44 Auto hidden +Int Property Stage3 = 51 Auto hidden +Int Property Stage4 = 58 Auto hidden +Int Property Stage5 = 65 Auto hidden + + + +Function SetMiraakCombatLevel() + Actor miraak = GetActorRef() + ;EquipSpell(DLC1dunHarkonConjureGargoyleLeftHand, 0) + + ;Other spells (Bats, Mistform, Invisibility, Conjure Gargoyle) are added, force-cast, and/or removed via script + ;on an as-needed basis. + + if (miraak.GetLevel() >= Stage4) + miraak.AddPerk( MageArmor30 ) + miraak.AddPerk( MageArmor50 ) + miraak.AddPerk( MagicResistance30 ) + miraak.AddPerk( MagicResistance50 ) + miraak.AddPerk( Bladesman60 ) + miraak.AddPerk( Bladesman90 ) + ElseIf (miraak.GetLevel() >= Stage3) + miraak.AddPerk( MageArmor30 ) + miraak.AddPerk( MageArmor50) + miraak.AddPerk( MagicResistance30 ) + miraak.AddPerk( Bladesman60 ) + ElseIf (miraak.GetLevel() >= Stage2) + miraak.AddPerk( MageArmor30 ) + miraak.AddPerk( MagicResistance30 ) + miraak.AddPerk( Bladesman60 ) + ElseIf (miraak.GetLevel() >= Stage1) + miraak.AddPerk( MageArmor30 ) + miraak.AddPerk( MagicResistance30 ) + Else + + EndIf +EndFunction +;/ +Function ReequipDrainSpell() + if (GetLevel() >= Stage4) + EquipSpell(DLC1DunHarkoncrVampireDrain06, 0) + EquipSpell(DLC1HarkonDrain06AltNew, 0) + ElseIf (GetLevel() >= Stage3) + EquipSpell(DLC1DunHarkoncrVampireDrain05, 0) + EquipSpell(DLC1HarkonDrain05AltNew, 0) + ElseIf (GetLevel() >= Stage2) + EquipSpell(DLC1DunHarkoncrVampireDrain04, 0) + EquipSpell(DLC1HarkonDrain04AltNew, 0) + ElseIf (GetLevel() >= Stage1) + EquipSpell(DLC1DunHarkoncrVampireDrain03, 0) + EquipSpell(DLC1HarkonDrain03AltNew, 0) + Else + EquipSpell(DLC1DunHarkoncrVampireDrain02, 0) + EquipSpell(DLC1HarkonDrain02AltNew, 0) + EndIf +EndFunction +/; + +;/ +SPELL Property ReanimateCorpseLeftHand Auto +SPELL Property RevenantLeftHand Auto +SPELL Property RaiseZombieLeftHand Auto +SPELL Property crVampireDrain02 Auto +SPELL Property crVampireDrain03 Auto +SPELL Property crVampireDrain04 Auto +SPELL Property crVampireDrain05 Auto +SPELL Property crVampireDrain06 Auto +/; +;Perk Property Necromancy Auto +;Perk Property SavageStrike Auto +Perk Property MagicResistance30 Auto +Perk Property MagicResistance50 Auto +;Perk Property HackAndSlash60 Auto +;Perk Property HackAndSlash90 Auto +Perk Property Bladesman60 Auto +Perk Property Bladesman90 Auto +;Perk Property WindWalker Auto +;Perk Property DarkSouls Auto +;Perk Property AugmentedFrost Auto +Perk Property MageArmor30 Auto +Perk Property MageArmor50 Auto + + +;Weapons +Weapon Property DLC2MKMiraakFightSword1 auto +Weapon Property DLC2MKMiraakFightSword2 auto +Weapon Property DLC2MKMiraakFightSword3 auto +Weapon Property DLC2MKMiraakFightSword4 auto +Weapon Property DLC2MKMiraakFightSword5 auto +Weapon Property DLC2MKMiraakFightSword6 auto + +Weapon Property DLC2MKMiraakFightStaff1 auto +Weapon Property DLC2MKMiraakFightStaff2 auto +Weapon Property DLC2MKMiraakFightStaff3 auto +Weapon Property DLC2MKMiraakFightStaff4 auto +Weapon Property DLC2MKMiraakFightStaff5 auto +Weapon Property DLC2MKMiraakFightStaff6 auto \ No newline at end of file diff --git a/source/scripts/dlc2miraakscript.psc b/source/scripts/dlc2miraakscript.psc new file mode 100644 index 00000000..b320d7c3 --- /dev/null +++ b/source/scripts/dlc2miraakscript.psc @@ -0,0 +1,126 @@ +Scriptname DLC2MiraakScript extends Actor +{Actor on base DLC2Miraak actors. Attach this if you need your Miraak to appear/disappear and call these functions.} + +;Notes: This assumes you only want him to AppearOnLoad once per Appear()/Disappear() function calls + +;PLEASE TALK TO jduvall BEFORE EDITING THIS SCRIPT. Thanks :) + +bool property AppearOnLoad auto +{Optional: default = false +If true will call the Appear() function without moving him to AppearAtRef, assuming you've already placed him where he needs to be} + +ObjectReference Property AppearAtRef auto +{Optional + When Miraak appears, where he is moved to. + For example, Player} + +ObjectReference Property DisappearToRef auto +{Optional (USE IF AppearOnLoad is true - other wise next time you are in the area he will appear) +When Miraak disappears, where he is moved to. +For example: +DLC2SoulStealMiraakSpawnMarker in DLC2aaaMarkers cell - an xmarker in a holding cell} + +Explosion Property DLC2MiraakTeleportExp auto +Explosion Property DLC2MiraakTeleportReturnExp auto + + + +EffectShader property DLC2MiraakTeleportStartFXS auto +EffectShader property DLC2MiraakTeleportReturnFXS auto + + + +ImageSpaceModifier Property DLC2MiraakTeleportIMODStatic auto + +bool Appeared + +Event OnUpdate() + ;assumes this is only ever called for the IMOD effect + + bool IMOD = false + + int distance = 1500 + + While Appeared + if GetDistance(Game.GetPlayer()) <= distance && IMOD == false + IMOD = true + DLC2MiraakTeleportIMODStatic.ApplyCrossFade(3) + endif + + if GetDistance(Game.GetPlayer()) > distance && IMOD == true + IMOD = false + ImageSpaceModifier.RemoveCrossFade(3) + endif + endWhile + + +EndEvent + + +Function OnLoad() + if AppearOnLoad && Appeared == false + Appeared = true + Appear(MoveToAppearAtRef = false) + endif + +EndFunction + +Function Appear(bool MoveToAppearAtRef = true, bool UseIMOD = true) + +; debug.trace(self + "Appear()") + + Appeared = true + + if MoveToAppearAtRef && AppearAtRef + MoveTo(AppearAtRef, 200) + endif + + if IsDisabled() + Enable(true) + endif + +; debug.trace(self + "setAlpha(0)") + setAlpha(0) + + +; debug.trace(self + "Placing Explosion.") + PlaceAtMe(DLC2MiraakTeleportExp) + + if UseIMOD + RegisterForSingleUpdate(0.001) + endif + +; debug.trace(self + "Waiting...") + utility.wait(2) + + setAlpha(1, true) + + DLC2MiraakTeleportStartFXS.play(self) + +; debug.trace(self + "setAlpha(1, true)") + + + +EndFunction + +Function Disappear() + + Appeared = false + + placeAtMe(DLC2MiraakTeleportReturnExp) + + DLC2MiraakTeleportReturnFXS.play(self) + + utility.wait(0.5) + + ImageSpaceModifier.RemoveCrossFade(3) + + setAlpha(0, true) + + Disable(true) + + if DisappearToRef + MoveTo(DisappearToRef) + endif + +EndFunction diff --git a/source/scripts/dlc2mq05hermaeusmorafxscript.psc b/source/scripts/dlc2mq05hermaeusmorafxscript.psc new file mode 100644 index 00000000..77ce6d57 --- /dev/null +++ b/source/scripts/dlc2mq05hermaeusmorafxscript.psc @@ -0,0 +1,87 @@ +Scriptname DLC2MQ05HermaeusMoraFXScript extends ObjectReference +{specific for MQ05 Skaal scene} + + +ObjectReference[] Property myHMface Auto + +int newState = 0 +int lastState = 0 +int iMaxCount = 10 ; max times to loop waiting for 3D to load + +auto State Waiting +; default state +endState + +State HermaeusMoraAppear + +Event OnBeginState() ;;;this bloc makes the hermaeus mora art appear + + int iIndex = lastState + while iIndex < newState +; debug.trace(self + " iIndex=" + iIndex) + if myHMFace[iIndex] +; debug.trace(self + " enabling " + myHMface[iIndex]) + myHMface[iIndex].disable() + ;;this delay gets same peices out of sync + utility.wait(Utility.RandomFloat(0.2, 0.5)) + myHMface[iIndex].enable() + int iCount = 0 + while !myHMface[iIndex].Is3DLoaded() && iCount < iMaxCount +; debug.trace(self + " iCount=" + iCount + ", is3dloaded=" + myHMface[iIndex].Is3DLoaded()) + iCount = iCount + 1 + utility.wait(Utility.RandomFloat(0.2, 0.5)) + endwhile + myHMface[iIndex].SetAnimationVariableFloat("fToggleBlend", 1.0) + endif + iIndex = iIndex + 1 + endWhile + ; save last state + lastState = newState +EndEvent + +endState + +State HermaeusMoraDisappear + +Event OnLoad() + ; failsafe in case HM was unloaded when changed to disappeared state + int iIndex = 0 + while iIndex < myHMface.length + if myHMface[iIndex] + myHMface[iIndex].Disable() + endif + iIndex = iIndex + 1 + endWhile +EndEvent + +Event OnBeginState() ;;;this bloc makes the hermaeus mora art disappear + int iIndex = 0 + while iIndex < lastState + if myHMface[iIndex] + utility.wait(Utility.RandomFloat(0.2, 0.5)) + myHMface[iIndex].SetAnimationVariableFloat("fToggleBlend", 0.0) + endif + iIndex = iIndex + 1 + endWhile + newState = 0 + lastState = 0 +EndEvent + +endState + +function ChangeState(bool bHermaeusMoraAppear = true, int iChangeToState = -1) + if bHermaeusMoraAppear + ; enable faces to new state + if iChangeToState == -1 + newState = newState + 1 + else + newState = iChangeToState + endif + GotoState("HermaeusMoraAppear") + else + gotoState("HermaeusMoraDisappear") + endif +endFunction + + + diff --git a/source/scripts/dlc2mq06miraakbossbattle.psc b/source/scripts/dlc2mq06miraakbossbattle.psc new file mode 100644 index 00000000..c894df8c --- /dev/null +++ b/source/scripts/dlc2mq06miraakbossbattle.psc @@ -0,0 +1,1098 @@ +ScriptName DLC2MQ06MiraakBossBattle extends ReferenceAlias +{This is the Main Fight Control Script for the Miraak Boss fight at the end of the DLC} + +;This script is a bit of a beast so I tried to break it up into many smaller functions +;In general, the ProcessOnUpdateOROnHitEvent Function is the major update loop +;There are several times where the sprint or teleport functions wait for a bool to be true +; These are set by the end of the scene they start or by the magic effect on the shout +; A timer was added as a safety measure in case something went wrong +; This was a pain to set up so tinker with it at your own peril +;The tentacle attacks that were originally part of the fight were disabled since it felt a bit too chaotic +;There are many properties like SelfActor and SelfRef, which might seem unnecessary +; This is to cut down on unneeded casting for clarity and performance +; better to cast it as an actor and store that once, then keep casting it over and over + +;General Actor Properties +Quest property DLC2MQ06 Auto +Actor property SelfActor auto hidden +ObjectReference property SelfRef auto hidden +Actor property PlayerActor auto hidden +ActorBase property selfBase auto hidden +Actor property ActorDragon1 auto hidden +Actor property ActorDragon2 auto hidden +Actor property ActorDragon3 auto hidden +Faction Property DLC2TameDragonFaction auto +Actor property TameDragon auto hidden +ReferenceAlias property Dragon1 auto +ReferenceAlias property Dragon2 auto +ReferenceAlias property Dragon3 auto +ReferenceAlias property TameDragonAlias auto + +;Initialization Properties +bool property scriptVariablesInitialized = false auto hidden +bool property initialized = false auto hidden +MusicType property DLC2MUSCombatBoss Auto +float property currentTime auto hidden + +bool property isMounted auto hidden +int property DragonBeingRidden = 1 auto hidden +bool property DragonRiddenWasFlying auto hidden +bool property DragonRiddenIsFlying auto hidden +bool property Dragon1isFlying auto hidden +bool property Dragon2isFlying auto hidden +bool property Dragon3isFlying auto hidden +bool property Dragon1isDead = false auto hidden +bool property Dragon2isDead = false auto hidden +bool property Dragon3isDead = false auto hidden +int property playerPosition = 0 auto hidden ;Didn't end up using this +{This property tells us where the player is, generally + 0 = Center + 1 = 2 o'clock + 2 = 3 o'clock + 3 = 5 o'clock + 4 = 7 o'clock + 5 = 9 o'clock + 6 = 11 o'clock} + +;Dragon Markers +objectReference property DLC2MQ06DragonLandingMarkerFar auto +objectreference Property DLC2MQ06DragonKillLandingMarker002 auto +objectreference Property DLC2MQ06DragonKillLandingMarker003 auto +bool Property CanSprintInCombat = True auto +bool property TameDragonShouldNeverLand = True auto +bool property fireMiraakKill = false auto +{Default = true} +;-------------------------------------------------------------- +;Initialization Block +;--------------------------------------- + +Function InitializeMiraakBattle() + if (!scriptVariablesInitialized) +; debug.Trace(self + ": INITIALIZING MIRAAK BATTLE") + InitializeScriptVariables() + EndIf +EndFunction + +Function InitializeScriptVariables() +; debug.Trace(self + ": Initializing Script Vars") + SetMiraakCombatLevel() + currentTime = Utility.GetCurrentRealTime() + TentacleTimer = currentTime + TentacleTimeDelayInit + TimeToSwapCombatStyle = currentTime + MaxTimeInMagicCombatStyle + ;TimeOfLastTeleport = currentTime + SelfActor = Self.GetActorRef() + SelfActor.StartDeferredKill() + selfBase = SelfActor.GetActorBase() + SelfRef = (SelfActor as objectreference) + PlayerActor = Game.GetPlayer() as Actor + ActorDragon1 = Dragon1.GetActorRef() + ActorDragon2 = Dragon2.GetActorRef() + ActorDragon3 = Dragon3.GetActorRef() + DLC2TameDragonOrbitMarker.moveto(SelfActor) + SelfBase.SetEssential(False) + SetRewardGear() + ((Self as referenceAlias) as DLC2MiraakCombatMagicLevelingScript).SetMiraakCombatLevel() + scriptVariablesInitialized = True + tentacleController = (DLC2MQBossTentacleControllerRef as DLC2MQBossTentacleController) + DLC2MiraakStreakE.Play(selfActor, -1) + ;sets mirakk fade speed + selfActor.SetSubGraphFloatVariable("fDampRate", fadeSpeedFast) ;sets how fast miraak fades in and out + CheckDragons() + if TameDragonShouldNeverLand + SetTameDragonCanLand(canLand = false) + endif +EndFunction + +Event OnCombatStateChanged(Actor akTarget, int aeCombatState) + if (!initialized) + initialized = True + if (!scriptVariablesInitialized) + InitializeScriptVariables() + EndIf + currentTime = Utility.GetCurrentRealTime() + ;TimeOfLastCombatStyleSwap = currentTime + ;TimeOfLastTeleport = currentTime +; ;Debug.Trace("Start the music!") + DLC2MUSCombatBoss.Add() + GoToState("Ready") + OnUpdate() + + EndIf +EndEvent +;-------------------------------------------------------------- +;States Block +;-------------------------------------------------------------- + +;Normal Combat State +Auto State Ready + Event onBeginState() +; Debug.Trace(self + ": Starting Ready State") + EndEvent + ;This is empty, but it uses the default onHit and ProcessOnUpdateOROnHitEvent + ;Other states will clear these so they do not run. +EndState + +;Busy State, in case needed +State Busy + Event onBeginState() +; Debug.Trace(self + ": Starting Busy State") + EndEvent + Event OnHit(ObjectReference aggressor, Form weap, Projectile proj, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + ;Do Nothing + EndEvent + Function ProcessOnUpdateOROnHitEvent(ObjectReference aggressor, Form weap) + ;Do Nothing + EndFunction +EndState + +State Done + Event onBeginState() +; Debug.Trace(self + ": Starting Done State") + EndEvent + Event OnHit(ObjectReference aggressor, Form weap, Projectile proj, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + ;Do Nothing + EndEvent + Function ProcessOnUpdateOROnHitEvent(ObjectReference aggressor, Form weap) + ;Do Nothing + EndFunction + Function OnUpdate() + ;Do Nothing + endFunction +EndState + +State runningMiraakDeathState + Event onBeginState() +; Debug.Trace(self + ": Starting runningMiraakDeathState State") + EndEvent + Event OnHit(ObjectReference aggressor, Form weap, Projectile proj, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + ;Do Nothing + EndEvent + Function ProcessOnUpdateOROnHitEvent(ObjectReference aggressor, Form weap) + ;Do Nothing + EndFunction + Function OnUpdate() + if fireMiraakKill + goToState("Done") + MiraakDeath() + else + RegisterForSingleUpdate(1) + endif + endFunction +endState +;-------------------------------------------------------------- +;Main Battle Loops: OnHit and OnUpdate +;--------------------------------------- + +;Every second, we check to see if we need to update Miraaks's state. +Function OnUpdate() + If !runningMiraakDeathEvent + ProcessOnUpdateOROnHitEvent(None, None) + RegisterForSingleUpdate(1) + EndIf +EndFunction + +;On hit, check to see which state we're in and respond accordingly. +Event OnHit(ObjectReference aggressor, Form weap, Projectile proj, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + ProcessOnUpdateOROnHitEvent(aggressor, weap) +EndEvent + +;*****************************************************************************; +;We have to handle both types of events in this single function to prevent interleaving errors from asynchronus events. +; This is where we kick off all the events +;*****************************************************************************; +Function ProcessOnUpdateOROnHitEvent(ObjectReference aggressor, Form weap) + if !runningMiraakDeathEvent + GoToState("Busy") + endif + float healthPercentage = SelfActor.GetAVPercentage("Health") + currentTime = Utility.GetCurrentRealTime() + isMounted = game.getPlayer().IsOnMount() + CurrentCombatStyle = DLC2MQ06MiraakCombatStyle.GetValue() as int + ;If all three dragons are not dead, check dragons + if !Dragon1isDead && !Dragon2isDead && !Dragon3isDead + CheckDragons() + endif + + If !scriptVariablesInitialized + ;if we aren't initialized don't do anything + elseif FightIsOver + GoToState("runningMiraakDeathState") + else + if totalDragonsKilled == 0 && healthPercentage <= dragonDrainThreshold1 && !runningDragonKillEvent && !sprintBusy + runningDragonKillEvent = True +; debug.Trace(self + ": DRAGON KILL EVENT 1") + sprintBusy = True + RunDragonKillEvent() + elseif totalDragonsKilled == 1 && healthPercentage <= dragonDrainThreshold2 && !runningDragonKillEvent && !sprintBusy + runningDragonKillEvent = True +; debug.Trace(self + ": DRAGON KILL EVENT 2") + sprintBusy = True + RunDragonKillEvent() + elseif totalDragonsKilled == 2 && healthPercentage <= dragonDrainThreshold3 && !runningDragonKillEvent && !sprintBusy + runningDragonKillEvent = True +; debug.Trace(self + ": DRAGON KILL EVENT 3") + sprintBusy = True + RunDragonKillEvent() + elseif totalDragonsKilled == 3 && healthPercentage <= finalKillThreshold && !runningDragonKillEvent && !runningMiraakDeathEvent && !sprintBusy + runningMiraakDeathEvent = true +; debug.Trace(self + ": MIRAAK KILL EVENT") + sprintBusy = True + RunMiraakDeathEvent() + ElseIf CanSprintInCombat && (aggressor == Game.GetPlayer()) && currentTime > (lastSprintTime + minTimebetweenSprints) && !sprintBusy && !runningDragonKillEvent && !runningMiraakDeathEvent && healthPercentage >= minSprintHealthThreshold +; ;Debug.Trace("Miraak: Registered normal hit.") + TimerPreviousHit06 = TimerPreviousHit05 + TimerPreviousHit05 = TimerPreviousHit04 + TimerPreviousHit04 = TimerPreviousHit03 + TimerPreviousHit03 = TimerPreviousHit02 + TimerPreviousHit02 = TimerPreviousHit01 + TimerPreviousHit01 = currentTime + + if selfActor.getDistance(playerActor) < 1000 && (TimerPreviousHit01 - TimerPreviousHit06 < 8) + sprintBusy = True + SprintAway(pickClosest = false) + PickNewCombatStyle() + ElseIf selfActor.getDistance(playerActor) >= 1000 && (TimerPreviousHit01 - TimerPreviousHit04 < 6) + sprintBusy = True + SprintAway(pickClosest = true) + PickNewCombatStyle() + EndIf + Endif + ;If (!SelfActor.IsInCombat()) + ; SelfActor.StartCombat(Game.GetPlayer()) + ;EndIf + + ;Make sure Miraak doesn't fall below ~50 health + ;If he does he won't run his packages correctly + if !runningMiraakDeathEvent + ;This should keep miraak above negative health + CheckMiraakHealthAndModIfNeeded() + endif + ;Combat Style Swap + if !runningDragonKillEvent && !runningMiraakDeathEvent + + if TimeToSwapCombatStyle <= currentTime && !IsMounted +; debug.Trace(self + ": Timer up - Time To Swap Combat Style") + PickNewCombatStyle() + elseif IsMounted && DragonRiddenWasFlying != DragonRiddenIsFlying +; debug.Trace(self + ": FlyingState change - Time To Swap Combat Style") + PickNewCombatStyle() + endif + endif + ;Check if it is okay to do tentacle attacks + ; okay = no alive dragons on the ground, and player not mounted + ;We decided the tentacle attacks were too much, but they can be turned back on + ;by setting the DoTentacleAttacks property to true + if DoTentacleAttacks + if Dragon1isFlying || Dragon1isDead + if Dragon2isFlying || Dragon2isDead + if Dragon3isFlying || Dragon3isDead + if !isMounted && !runningMiraakDeathEvent && !runningDragonKillEvent + ;This is where we kick off tentacle attacks + if TentacleTimer <= currentTime ;&& "Player is on the ground" +; debug.Trace(self + ": Time for Tentacle Attack") + int TargetArea = utility.randomInt(-1,6) +; debug.Trace(self + ": Tentacle Target Area = " + TargetArea) + TriggerTentacleAttack(TargetArea) + TentacleTimer = currentTime + TentacleTimeDelay + endif + EndIf + EndIf + endif + endif + Endif + endif + if !runningMiraakDeathEvent && !runningDragonKillEvent + GoToState("Ready") + endif +EndFunction + +Function CheckDragons() + bool TameDragonFound = false + if !Dragon1isDead + Dragon1isFlying = ActorDragon1.isFlying() + if !TameDragonFound && ActorDragon1.IsInFaction(DLC2TameDragonFaction) + TameDragon = ActorDragon1 + TameDragonFound = true + EndIf + EndIf + if !Dragon2isDead + Dragon2isFlying = ActorDragon2.isFlying() + if !TameDragonFound && ActorDragon2.IsInFaction(DLC2TameDragonFaction) + TameDragon = ActorDragon2 + TameDragonFound = true + EndIf + EndIf + if !Dragon3isDead + Dragon3isFlying = ActorDragon3.isFlying() + if !TameDragonFound && ActorDragon3.IsInFaction(DLC2TameDragonFaction) + TameDragon = ActorDragon3 + TameDragonFound = true + EndIf + EndIf + if !TameDragonFound + TameDragon = None + DragonRiddenWasFlying = False + DragonRiddenIsFlying = False + else + DragonRiddenWasFlying = DragonRiddenIsFlying + DragonRiddenIsFlying = TameDragon.IsFlying() + endif + TameDragonAlias.ForceRefTo(TameDragon) +EndFunction + +;-------------------------------------------------------------- +;Dragon Kill Functions +;-------------------------------------------------------------- +;Properties for Dragon Drain Events and overall combat Tracking +float property dragonDrainThreshold1 = 0.3 auto hidden +float property dragonDrainThreshold2 = 0.3 auto hidden +float property dragonDrainThreshold3 = 0.3 auto hidden +float property minSprintHealthThreshold = 0.5 auto hidden +float property finalKillThreshold = 0.1 auto hidden +int property totalDragonsKilled = 0 auto hidden +bool property runningDragonKillEvent = false auto hidden +bool property runningMiraakDeathEvent = false auto hidden +bool property FightIsOver = false auto hidden +spell property DLC2MiraakDragonKillSpell auto +Scene Property DLC2MQ06MiraakKillDragonScene Auto +ReferenceAlias Property DragonToKillAlias Auto +Actor Property DragonToKill auto hidden +spell property DLC2MiraakFakeShoutSpell auto +bool property waitingForDragonKillSceneToEnd auto hidden +bool property PreferToKillPlayerDragon = False auto +Quest Property DLC2TameDragon auto +;DLC2TameDragonScript is the script used +; We call ReleaseDragon() when we kill the tamed dragon + +Function MiraakStealsSoul() +; debug.Trace(self + ": MIRAAK STEALS DRAGON SOUL") + totalDragonsKilled += 1 + ; update MQ06 to use in conditions + (GetOwningQuest() as DLC2MQ06Script).MiraakDragonsKilled = totalDragonsKilled + selfActor.RestoreActorValue("health", 1000) +; debug.Trace(self + ": END FIGHT DRAGONS KILLED = " + totalDragonsKilled) +endFunction + +Function RunDragonKillEvent() + ;int sceneWaitSafety = 0 + objectReference dragonKillLandingMarker +; debug.Trace(self + ": RUNNING DRAGON KILL EVENT") + ;Select which dragon we are going to kill + PickDragonToKill() +; debug.Trace(self + ": DragonToKill = " + DragonToKill) + + if totalDragonsKilled == 0 + dragonKillLandingMarker = DLC2MQ06DragonKillLandingMarker002 + ElseIf totalDragonsKilled == 1 + dragonKillLandingMarker = DLC2MQ06DragonKillLandingMarker003 + Elseif totalDragonsKilled == 2 + dragonKillLandingMarker = DLC2MQ06DragonLandingMarkerFar + endif + ;If this is the tamed dragon and the player is not riding it, release the dragon. + if DragonToKill == TameDragon && !isMounted + (DLC2TameDragon as DLC2TameDragonScript).ReleaseDragon() + endif + ; Set Dragon to Kill alias + DragonToKill.SetForcedLandingMarker(dragonKillLandingMarker) + + DragonToKill.SetAllowFlying(false) + SetDragonNoLand() + ;;;;;;;;!!!! + DragonToKill.StartDeferredKill() + if DragonToKill.isflying() + DragonToKill.damageAV("health", 5000) + endif + DragonToKillAlias.ForceRefTo(DragonToKill) + ;Move Miraak to safe room + objectReference teleportAwayTarget = PickTeleportMarkerNearby() + SelfActor.AddSpell(DLC2MiraakEtherealFXSpell) + selfActor.SetGhost(true) + SprintToTargetAndTeleportAway(teleportAwayTarget) + +EndFunction + +Function SetDragonNoLand() + if !Dragon1isDead && ActorDragon1 != DragonToKill + ActorDragon1.SetAV("Variable07", 1) + ActorDragon1.EvaluatePackage() + endif + if !Dragon2isDead && ActorDragon2 != DragonToKill + ActorDragon2.SetAV("Variable07", 1) + ActorDragon2.EvaluatePackage() + endif + if !Dragon3isDead && ActorDragon3 != DragonToKill + ActorDragon3.SetAV("Variable07", 1) + ActorDragon3.EvaluatePackage() + endif +endFunction + +Function SetDragonsCanLand() + if !Dragon1isDead && ActorDragon1 != TameDragon + ActorDragon1.SetAV("Variable07", 0) + ActorDragon1.EvaluatePackage() + endif + if !Dragon2isDead && ActorDragon1 != TameDragon + ActorDragon2.SetAV("Variable07", 0) + ActorDragon2.EvaluatePackage() + endif + if !Dragon3isDead && ActorDragon1 != TameDragon + ActorDragon3.SetAV("Variable07", 0) + ActorDragon3.EvaluatePackage() + endif +endFunction + +bool TameDragonCanLandCurrently +Function SetTameDragonCanLand(bool canLand = true) + TameDragonCanLandCurrently = canLand + if !TameDragon.isDead() + if canLand + ActorDragon1.SetAV("Variable07", 0) + else + ActorDragon1.SetAV("Variable07", 1) + endif + ActorDragon1.EvaluatePackage() + EndIf +endFunction + +Actor Function PickDragonToKill() + DragonToKill = NONE + if PreferToKillPlayerDragon + ;If we prefer to kill the player's dragon... + DragonToKill = TameDragon + elseif totalDragonsKilled < 2 + ;Pick a dragon that is not the player's tamed dragon + if !Dragon1isDead && ActorDragon1 != TameDragon + DragonToKill = ActorDragon1 + elseif !Dragon2isDead && ActorDragon2 != TameDragon + DragonToKill = ActorDragon2 + elseif !Dragon3isDead && ActorDragon3 != TameDragon + DragonToKill = ActorDragon3 + EndIf + else ;There is only one dragon left, pick which ever it is + if !Dragon1isDead ;&& ActorDragon1 != TameDragon + DragonToKill = ActorDragon1 + elseif !Dragon2isDead ;&& ActorDragon2 != TameDragon + DragonToKill = ActorDragon2 + elseif !Dragon3isDead ;&& ActorDragon3 != TameDragon + DragonToKill = ActorDragon3 + EndIf + endif +endFunction + +Function DragonKillSceneEnded() + waitingForDragonKillSceneToEnd = False +; debug.Trace(self + ": Dragon Kill Scene has ended") + if !DragonToKill.isDead() + DragonToKill.EndDeferredKill() + DragonToKill.damageAV("health", 10000) + endif + self.getActorRef().RemoveSpell(DLC2MiraakFakeShoutSpell) + ;while !DragonToKill.isDead() + ; utility.wait(2.0) + ;endwhile + while selfActor.GetAVPercentage("health") < 0.9 + utility.wait(0.5) + endwhile + ;selfBase.SetEssential(True) + selfActor.SetGhost(False) + SelfActor.RemoveSpell(DLC2MiraakEtherealFXSpell) + SetDragonsCanLand() + runningDragonKillEvent = false + GoToState("Ready") +endFunction + +;This function tracks with dragons have already been killed +Function TrackDragonDeath(int DragonNumber) +; Debug.trace(Self + "TrackDragonDeath >> DragonKilled = " + DragonNumber) + if DragonNumber == 1 + Dragon1isDead = True + if DragonToKill == ActorDragon1 && waitingForDragonKillSceneToEnd + DragonKillSceneEnded() + EndIf + elseif DragonNumber == 2 + Dragon2isDead = True + if DragonToKill == ActorDragon2 && waitingForDragonKillSceneToEnd + DragonKillSceneEnded() + EndIf + elseif DragonNumber == 3 + Dragon3isDead = True + if DragonToKill == ActorDragon3 && waitingForDragonKillSceneToEnd + DragonKillSceneEnded() + EndIf + endif +endFunction + +;-------------------------------------------------------------- +;Miraak Kill Functions +;-------------------------------------------------------------- +;MiraakDeathSequence Properties +VisualEffect Property DragonAbsorbEffect Auto +VisualEffect Property DragonAbsorbManEffect Auto +sound property NPCDragonDeathSequenceWind auto +sound property NPCDragonDeathSequenceExplosion auto +EffectShader Property DragonPowerAbsorbFXS Auto +Spell Property DLC2KillMiraakSpell auto +GlobalVariable Property DLC2SoulStealCount Auto +objectReference property MQ06MiraakDeathMarker auto +idle property IdleDLC02MiraakDeathFinish auto +Armor Property DLC2MiraakSkeleton Auto ; miraaks skeleton for death fx +ObjectReference property DLC2MQ06CenterPoolRef auto +ObjectReference property DLC2MQ06CenterPoolFakeRef auto + +VisualEffect Property DLC2MiraakAbsorbManE Auto ;..autofills +VisualEffect Property DLC2MiraakAbsorbE Auto ;...autofills + + +EffectShader Property DLC2MiraakBitsFXS Auto +EffectShader Property DLC2MiraakBitsLite2FXS Auto +EffectShader Property DLC2MiraakSmokeFXS Auto +EffectShader Property DLC2MiraakMagicFXS Auto +Armor Property DLC2MiraakSkinHider auto +Sound Property QSTMiraakDeathBurnMarker auto + +Function RunMiraakDeathEvent() + ;runningMiraakDeathEvent == True +; Debug.Trace(self + ": RunMiraakDeathEvent") + GoToState("runningMiraakDeathState") + ;Enable the fake water plane in the center and disable the real one + ;Thjs is necessary for Miraak to be able to enter the furniture while under the platform + ;DLC2MQ06CenterPoolFakeRef.enable(abFadeIn = false) + ;DLC2MQ06CenterPoolRef.disable(abFadeout = True) + objectReference teleportAwayTarget = PickTeleportMarkerNearby() + SelfActor.AddSpell(DLC2MiraakEtherealFXSpell) + selfActor.SetGhost(true) + SprintToTargetAndTeleportAway(teleportAwayTarget) + +endFunction + +Event MiraakDeath() +; Debug.Trace(self + ": MiraakDeath") +; This is the bit that plays the absorb stuff, needed to move it up for Miraak + ;display dragon absorb effect art. One part on dragon one part on player. + ;mirak fades down + DLC2MiraakBitsLite2FXS.Play(selfActor) + utility.wait(1) + selfActor.playSubgraphAnimation("SkinFadeOutLong") + QSTMiraakDeathBurnMarker.Play(SelfActor) + DLC2MiraakBitsFXS.Play(selfActor) + utility.wait(0.1) + selfActor.playSubgraphAnimation("stage2") + + + utility.wait(3) + DLC2MiraakMagicFXS.Play(selfActor) + DLC2MiraakMagicFXS.Stop(selfActor) + utility.wait(3) + selfActor.Playidle(IdleDLC02MiraakDeathFinish) + + DLC2MiraakBitsLite2FXS.Stop(selfActor) + DLC2MiraakBitsFXS.Stop(selfActor) + DragonAbsorbEffect.Play(SelfActor, 8, PlayerActor) ;***DLC2: CHANGED FROM GetPlayer() to AbsorbActor +;; dragonRef.placeAtME(MAGDragonPowerAbsorbExplosion) + DragonAbsorbManEffect.Play(PlayerActor, 8, SelfActor) ;***DLC2: CHANGED FROM GetPlayer() to AbsorbActor + NPCDragonDeathSequenceWind.play(SelfActor) + NPCDragonDeathSequenceExplosion.play(SelfActor) + utility.wait(1.0) +;;;;;;;;;;;;;Start of what actually kills Miraak;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;The Combat Spell Apllied here ends the Deferred Kill + selfActor.SetGhost(false) + ;equip the skin hider so we don't see bare hands & feet + SelfActor.Equipitem(DLC2MiraakSkinHider) + ;This is the spell that actually KILLS Miraak + PlayerActor.doCombatSpellApply(DLC2KillMiraakSpell, selfActor) + + ;Tell the Tentacle furniture to finish playing and retract + MQ06MiraakDeathMarker.PlayAnimation("TPlay02") + ; Sounds for when the wispy particles being to fly at the player. +;;;;;;;;;THis is the end of the actual kill stuff + + utility.wait(10) + DLC2MiraakSmokeFXS.Play(selfActor) + utility.wait(3) + DLC2MiraakSmokeFXS.Stop(selfActor) + utility.wait(2) + selfActor.playSubgraphAnimation("stage3") + + ;utility.wait(3.0) + + DLC2MUSCombatBoss.Remove() + ;Make it rain!!! (souls) + PlayerActor.ModActorValue("DragonSouls", 3 + DLC2SoulStealCount.GetValueInt() + totalDragonsKilled) + DragonPowerAbsorbFXS.Stop(PlayerActor) ;***DLC2: CHANGED FROM GetPlayer() to AbsorbActor +endEvent +;-------------------------------------------------------------- +;Fight Utility Functions +;--------------------------------------- +;;;;;;;;;;;;;;;;CombatStyle Functions;;;;;;;;;;;;;;;;;;;;; + +;Combat Style Properties +weapon property MiraakSword auto hidden +;weapon property DLC2MiraakApocryphaSword auto +weapon property MiraakStaff auto hidden +Spell Property DLC2LightningStormRightHand auto +objectreference property Sword1 auto hidden +objectreference property Staff auto hidden +objectreference property DLC2TameDragonOrbitMarker auto +float TimeToSwapCombatStyle = 0.0 +float MaxTimeInMagicCombatStyle = 30.0 +float MaxTimeInStaffCombatStyle = 10.0 +float MaxTimeInMeleeCombatStyle = 30.0 +GlobalVariable property DLC2MQ06MiraakCombatStyle auto +{This variable controls which combat style Miraak is using. +This is set via combat override Package. +It also is used to adjust his spells and equipment when changing combat style. + 0 = Staff + 1 = Magic (noStaff) + 2 = Melee + 3 = AntiAir (Kill Players flying Dragon)} +int property CurrentCombatStyle auto hidden + +Function PickNewCombatStyle() +; debug.Trace(self + ": Running SwapMiraakCombatStyle") + CurrentCombatStyle = DLC2MQ06MiraakCombatStyle.GetValue() as int + int NewCombatStyle = CurrentCombatStyle + if isMounted && TameDragon && DragonRiddenIsFlying + ChangeMiraakCombatStyle(3);Use AntiAir + else + ;Ensure we are using a new combat style + While NewCombatStyle == CurrentCombatStyle + NewCombatStyle = utility.RandomInt(0,2) + endWhile + ChangeMiraakCombatStyle(NewCombatStyle) + endif +endFunction + +Function ChangeMiraakCombatStyle(int NewCombatStyle = 1) +; debug.Trace(self + ": Running ChangeMiraakCombatStyle NewCombatStyle = " + NewCombatStyle) + if NewCombatStyle == 0 ;Staff + ;Set the global that changes his combat override packages + DLC2MQ06MiraakCombatStyle.SetValue(0) + ;Remove Spells & Equipment + if Sword1 + selfActor.removeItem(sword1) + SelfActor.UnequipItem(sword1) + endif + SelfActor.RemoveSpell(DLC2LightningStormRightHand) + SelfActor.UnEquipSpell(DLC2LightningStormRightHand, 1) + ;Add Spells & Equipment + Staff = SelfActor.EquipItem(MiraakStaff) + + ;Reset the combat Timer + TimeToSwapCombatStyle = currentTime + MaxTimeInStaffCombatStyle + elseif NewCombatStyle == 1 ;Magic (NoStaff) + ;Set the global that changes his combat override packages + DLC2MQ06MiraakCombatStyle.SetValue(1) + ;Remove Spells & Equipment + if Sword1 + SelfActor.UnequipItem(sword1) + selfActor.removeItem(sword1) + endif + if Staff + SelfActor.UnequipItem(Staff) + selfActor.removeItem(Staff) + endif + SelfActor.RemoveSpell(DLC2LightningStormRightHand) + SelfActor.UnEquipSpell(DLC2LightningStormRightHand, 1) + ;Add Spells & Equipment + + ;Reset the combat Timer + TimeToSwapCombatStyle = currentTime + MaxTimeInMeleeCombatStyle + elseif NewCombatStyle == 2 ;Melee + ;Set the global that changes his combat override packages + DLC2MQ06MiraakCombatStyle.SetValue(2) + ;Remove Spells & Equipment + SelfActor.RemoveSpell(DLC2LightningStormRightHand) + SelfActor.UnEquipSpell(DLC2LightningStormRightHand, 1) + if Staff + SelfActor.UnequipItem(Staff) + selfActor.removeItem(Staff) + endif + ;Add Spells & Equipment + sword1 = SelfActor.EquipItem(MiraakSword) + + ;Reset the combat Timer + TimeToSwapCombatStyle = currentTime + MaxTimeInMagicCombatStyle + ElseIf NewCombatStyle == 3 ;AntiAir + ;Set the global that changes his combat override packages + DLC2MQ06MiraakCombatStyle.SetValue(3) + ;Remove Spells & Equipment + if Sword1 + SelfActor.UnequipItem(sword1) + selfActor.removeItem(sword1) + endif + if Staff + SelfActor.UnequipItem(Staff) + selfActor.removeItem(Staff) + endif + ;Add Spells & Equipment + SelfActor.AddSpell(DLC2LightningStormRightHand) + + ;Reset the combat Timer + TimeToSwapCombatStyle = currentTime + 10.0 + Else +; debug.Trace(self + ": ChangeCombatStyle was passed invalid int >> " + NewCombatStyle) + endif + + SelfActor.EvaluatePackage() +endFunction + +Function CheckMiraakHealthAndModIfNeeded() + float miraakHealth = selfActor.getActorValue("health") + if miraakHealth < 10.0 + if miraakHealth < 0.0 + miraakHealth = 0 - miraakHealth + EndIf + selfActor.RestoreActorValue("Health", 10.0 + miraakHealth) + endif +EndFunction +;;;;;;;;;;;;;;;;End of CombatStyle Functions;;;;;;;;;;;;;;;;;;;;; + + +;Setting this inside the script to avoid interleaving errors +Function setPlayerPositionVariable(int newPosition) + playerPosition = newPosition +endFunction + +;;;;;;;;;;;;;;;;Sprint Functions;;;;;;;;;;;;;;;;;;;;; + +;Whirlwind Sprint Properties +ReferenceAlias Property SprintTarget auto +Scene Property DLC2MQ06MiraakSprintScene auto +bool Property waitingForSprintSceneToEnd auto hidden +objectreference[] Property DLC2MQ06SprintTargets auto +Spell Property DLC2MiraakEtherealFXSpell auto + +Function SprintAway(bool pickClosest = false) + objectreference Target + Target = PickSprintAwayTarget(pickClosest) + ;FadeInSprintFX() +; ;debug.Trace(self + ": Sprinting to Target= " + Target) + SprintTarget.ForceRefTo(Target) + SelfActor.AddSpell(DLC2MiraakEtherealFXSpell) + selfActor.SetGhost(true) + DLC2MQ06MiraakSprintScene.start() +endFunction + + +Function SprintToTarget(objectreference Target) +; ;debug.Trace(self + ": Sprinting to Target= " + Target) + ;FadeInSprintFX() + ;utility.wait(0.2) + int sceneWaitSafety = 0 + waitingForSprintSceneToEnd = True + SprintTarget.ForceRefTo(Target) + DLC2MQ06MiraakSprintScene.start() + ;/ + While waitingForSprintSceneToEnd && sceneWaitSafety < 20 + utility.Wait(0.2) +; debug.Trace(self + ": Waiting for Sprint Scene To End >> " + sceneWaitSafety) + sceneWaitSafety += 1 + CheckMiraakHealthAndModIfNeeded() + endWhile + /; + ;FadeInSprintFX() +endFunction + +Function SprintToTargetAndTeleportAway(objectreference Target) + int sceneWaitSafety = 0 +; debug.Trace(self + ": SprintToTargetAndTeleportAway Target= " + Target) + teleportBusy = true + SprintToTarget(Target) + ;/ + waitingForSprintSceneToEnd = True + While waitingForSprintSceneToEnd && sceneWaitSafety < 4 + utility.Wait(1.0) +; debug.Trace(self + ": Waiting for Sprint Scene To End >> " + sceneWaitSafety) + sceneWaitSafety += 1 + CheckMiraakHealthAndModIfNeeded() + endWhile + /; + ;TeleportAway() +endFunction + +Function SprintSceneEnded() + ;utility.wait(0.1) + ;FadeOutSprintFX() +; Debug.Trace(self + ": SprintSceneEnded") + lastSprintTime = currentTime + if waitingForSprintSceneToEnd + waitingForSprintSceneToEnd = False + TeleportAway() + elseif !runningMiraakDeathEvent && !runningDragonKillEvent + SelfActor.RemoveSpell(DLC2MiraakEtherealFXSpell) + selfActor.SetGhost(false) + waitingForSprintSceneToEnd = False + endif + sprintBusy = False +; debug.Trace(self + ": Sprint Scene has ended") +endFunction + +ObjectReference Function PickSprintAwayTarget(bool pickClosest = false) + ObjectReference NewSprintTarget + ;Identify the closest teleport point, offset from it +/-2, and go there. + int closestPoint = 0 + int i = 0 + float ClosestDistance = 6000.0 + float Distance = 0.0 + float MinDistance = 2000.0 + int listLength = DLC2MQ06SprintTargets.Length - 1 +; Debug.Trace(self + "DLC2MQ06SprintTargets length = " + listLength) + if pickClosest + While (i < listLength) + Distance = playerActor.getDistance(DLC2MQ06SprintTargets[i]) + if (Distance < ClosestDistance) + NewSprintTarget = DLC2MQ06SprintTargets[i] + ClosestDistance = Distance + EndIf + i = i + 1 + EndWhile + else + Distance = 0.0 + While Distance < MinDistance + i = utility.RandomInt(0, DLC2MQ06SprintTargets.Length) + NewSprintTarget = DLC2MQ06SprintTargets[i] + Distance = playerActor.getDistance(NewSprintTarget) + EndWhile + endif + return NewSprintTarget +EndFunction + + + +;;;;;;;;;;;;;;;;End of Sprint Functions;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;Teleport Functions;;;;;;;;;;;;;;;;;;;;; +;Teleport Properties +objectreference property DLC2MiraakFightTeleportMarkerMid auto +objectreference property DLC2MiraakFightTeleportMarker01 auto +objectreference property DLC2MiraakFightTeleportMarker02 auto +objectreference property DLC2MiraakFightTeleportMarker03 auto +objectreference property DLC2MiraakFightTeleportMarker04 auto +objectreference property DLC2MiraakFightTeleportMarker05 auto +objectreference property DLC2MiraakFightTeleportMarker06 auto +objectreference property DLC2MQ06FightFallTeleportMarker auto +objectreference property DLC2MQ06KillSceneFallTeleportMarker auto +FormList Property DLC2MQ06TeleportTargetFL auto +objectreference property DLC2MQ06MiraakSaferoom auto +Explosion Property DLC2MQ06MiraakTeleportExplosion auto +Explosion Property DLC2MiraakAwayExplosion auto +Explosion Property DLC2MiraakBackExplosion auto +Scene property DLC2MQ06PlayerFallRecoveryScene auto +Scene property DLC2MQ06MiraakFallRecoveryScene auto + +;objectReference[] property TeleportPoints auto +;Static property MiraakTeleportMarker Auto + +float fadeSpeedDefault = 0.03 ; this is the default value of fDampRate fades over about 2 seconds +float fadeSpeedFast = 0.05 ; about 1 second fade time + +VisualEffect Property DLC2MiraakStreakE Auto ;streak art...autofills +bool teleportFromOffCliff = false +bool teleportBusy +Function TeleportMiraakFromOffCliff() +; Debug.Trace(self + ": TeleportMiraakFromOffCliff>> ") +; Debug.Trace("runningMiraakDeathEvent = " + runningMiraakDeathEvent + " > runningDragonKillEvent = " + runningDragonKillEvent) + if !teleportBusy + teleportFromOffCliff = true + if runningMiraakDeathEvent && !SelfActor.isDead() + TeleportMiraak(DLC2MQ06KillSceneFallTeleportMarker) + else + TeleportAway() + endif + endif +EndFunction + +Function TeleportPlayerFromOffCliff() +; Debug.Trace(self + ": TeleportPlayerFromOffCliff") + game.GetPlayer().PlaceAtMe(DLC2MQ06MiraakTeleportExplosion) + DLC2MQ06FightFallTeleportMarker.PlaceAtMe(DLC2MQ06MiraakTeleportExplosion) + game.GetPlayer().MoveTo(DLC2MQ06FightFallTeleportMarker) +EndFunction + +Function TeleportMiraak(objectReference teleportTarget) +; Debug.Trace(self + ": TeleportMiraak to >> " + teleportTarget) + teleportTarget.PlaceAtMe(DLC2MiraakBackExplosion) + utility.wait(0.1) + selfActor.moveto(teleportTarget) + ;miraak fades up + ;utility.wait(0.05) + If !SelfActor.isDead() + selfActor.playSubgraphAnimation("SkinFadeIn") + endif + teleportBusy = false +endFunction + +Function TeleportAway() +; Debug.Trace(self + ": TeleportAway>>") +; Debug.Trace("runningMiraakDeathEvent = " + runningMiraakDeathEvent + " > runningDragonKillEvent = " + runningDragonKillEvent) + teleportBusy = true + selfActor.PlaceAtMe(DLC2MiraakAwayExplosion) + selfActor.moveto(DLC2MQ06MiraakSaferoom) + ;If we are in the MiraakDeathEvent move to the furniture and start the scene + if runningMiraakDeathEvent +; Debug.Trace(self + ": TeleportAway >>> runningMiraakDeathEvent") + selfActor.equipItem(DLC2MiraakSkeleton) + SelfActor.RemoveSpell(DLC2MiraakEtherealFXSpell) + DLC2MiraakStreakE.Stop(selfActor) + SelfActor.Moveto(MQ06MiraakDeathMarker) + DLC2MQ06.SetStage(500) + teleportBusy = false + elseif runningDragonKillEvent +; Debug.Trace(self + ": TeleportAway >>> runningDragonKillEvent") + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!! + while DragonToKill.isflying() && !DragonToKill.isDead() + utility.wait(1.0) +; debug.Trace(self + ": DragonKill waiting for landing") + endWhile + self.getActorRef().AddSpell(DLC2MiraakFakeShoutSpell) + waitingForDragonKillSceneToEnd = True + DLC2MQ06MiraakKillDragonScene.Start() + TeleportMiraak(DLC2MiraakFightTeleportMarkerMid) + elseif teleportFromOffCliff +; Debug.Trace(self + ": TeleportAway >>> teleportFromOffCliff") + teleportFromOffCliff = false + utility.Wait(0.2) + TeleportMiraak(DLC2MQ06FightFallTeleportMarker) + if !SelfActor.isDead() + DLC2MQ06MiraakFallRecoveryScene.Start() + endif + teleportBusy = false + endif +EndFunction + + +Function TeleportPlayerToTarget(objectreference teleportTarget) +; Debug.Trace(self + ": TeleportPlayerToTarget") + teleportTarget.PlaceAtMe(DLC2MQ06MiraakTeleportExplosion) + Game.getPlayer().moveto(teleportTarget) + DLC2MQ06PlayerFallRecoveryScene.Start() +endFunction + +ObjectReference Function PickTeleportMarkerNearby() + ObjectReference closestMarker = Game.FindClosestReferenceOfAnyTypeInList(DLC2MQ06TeleportTargetFL, selfRef.getPositionX(), selfRef.getPositionY(), selfRef.getPositionZ(), 6000.0) + if (closestMarker == None) +; Debug.Trace(self + ": Could not pick nearby Teleport point!!!") + EndIf + + + return closestMarker +EndFunction +;;;;;;;;;;;;;;;;End of Teleport Functions;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;Tentacle Attack Functions;;;;;;;;;;;;;;;;;;;;; +;The following functions are for talking to the tentacle attack controller +;Properties for Tentacle Controller +DLC2MQBossTentacleController property tentacleController auto hidden +objectreference property DLC2MQBossTentacleControllerRef auto +float property TentacleTimer auto hidden +float property TentacleTimeDelayInit = 15.0 auto hidden +float property TentacleTimeDelay = 15.0 auto hidden +bool property DoTentacleAttacks = false auto + +Function TriggerTentacleAttack(int TargetArea) + if TargetArea == -1 ;Attack FULL + TriggerTentacleAttackFull(bClockwise = false, fAttackTimer = 0.5) + elseif TargetArea >= 0 && TargetArea <= 6 + TriggerTentacleAttackSingle(TargetArea, bClockwise = false, fAttackTimer = 0.5) + EndIf +EndFunction + +Function TriggerTentacleAttackFull(bool bClockwise = false, float fAttackTimer = 0.5) + ;Set properties then register for single update + ; RegisterForSingleUpdate is used to kick off new thread + tentacleController.fullSweep = true + tentacleController.clockwise = bClockwise + tentacleController.attackTimer = fAttackTimer + tentacleController.RegisterForSingleUpdate(0.1) +endFunction + +Function TriggerTentacleAttackSingle(int itargetArea = 1, bool bClockwise = false, float fAttackTimer = 0.5) + ;Set properties then register for single update + ; RegisterForSingleUpdate is used to kick off new thread + tentacleController.targetArea = itargetArea + tentacleController.clockwise = bClockwise + tentacleController.attackTimer = fAttackTimer + tentacleController.RegisterForSingleUpdate(0.1) +endFunction + +;;;;;;;;;;;;;;;;Miraak Combat Leveling Function;;;;;;;;;;;;;;;;;;;;; +;Weapons + +Int Property Stage1 = 37 Auto hidden +Int Property Stage2 = 44 Auto hidden +Int Property Stage3 = 51 Auto hidden +Int Property Stage4 = 58 Auto hidden +Int Property Stage5 = 65 Auto hidden + +Weapon Property DLC2MKMiraakFightSword1 auto +Weapon Property DLC2MKMiraakFightSword2 auto +Weapon Property DLC2MKMiraakFightSword3 auto +Weapon Property DLC2MKMiraakFightSword4 auto +Weapon Property DLC2MKMiraakFightSword5 auto +Weapon Property DLC2MKMiraakFightSword6 auto + +Weapon Property DLC2MKMiraakFightStaff1 auto +Weapon Property DLC2MKMiraakFightStaff2 auto +Weapon Property DLC2MKMiraakFightStaff3 auto +Weapon Property DLC2MKMiraakFightStaff4 auto +Weapon Property DLC2MKMiraakFightStaff5 auto +Weapon Property DLC2MKMiraakFightStaff6 auto + +Function SetMiraakCombatLevel() + Actor miraak = GetActorRef() + ;Pick the leveled gear that Miraak will use and store it + if (miraak.GetLevel() >= Stage5) + MiraakSword = DLC2MKMiraakFightSword6 + MiraakStaff = DLC2MKMiraakFightStaff6 + elseif (miraak.GetLevel() >= Stage4) + MiraakSword = DLC2MKMiraakFightSword5 + MiraakStaff = DLC2MKMiraakFightStaff5 + ElseIf (miraak.GetLevel() >= Stage3) + MiraakSword = DLC2MKMiraakFightSword4 + MiraakStaff = DLC2MKMiraakFightStaff4 + ElseIf (miraak.GetLevel() >= Stage2) + MiraakSword = DLC2MKMiraakFightSword3 + MiraakStaff = DLC2MKMiraakFightStaff3 + ElseIf (miraak.GetLevel() >= Stage1) + MiraakSword = DLC2MKMiraakFightSword2 + MiraakStaff = DLC2MKMiraakFightStaff2 + Else ;base gear + MiraakSword = DLC2MKMiraakFightSword1 + MiraakStaff = DLC2MKMiraakFightStaff1 + EndIf +EndFunction + +;;;;;;;;;;;;;;;;End Miraak Combat Leveling Function;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;Set Reward Gear Function;;;;;;;;;;;;;;;;;;;;; + ;Ended up doing this thorough DeathItems but kept the old script here + ;This function controls if we give the player light or heavy mask +GlobalVariable Property DLC2MQ06MaskHeavyChance auto +GlobalVariable Property DLC2MQ06MaskLightChance auto +Function SetRewardGear() + if playerActor.getActorValue("Heavyarmor") > playerActor.getActorValue("LightArmor") + DLC2MQ06MaskHeavyChance.SetValue(0) + DLC2MQ06MaskLightChance.SetValue(100) + else + DLC2MQ06MaskLightChance.SetValue(0) + DLC2MQ06MaskHeavyChance.SetValue(100) + endif +EndFunction +Function SwapToRewardGear() +EndFunction +;;;;;;;;;;;;;;;;End Reward Gear Function;;;;;;;;;;;;;;;;;;;;; + +;Hit Timestamps +float TimerPreviousHit01 = 0.0 ;Timestamps that record when the player hits Miraak with an attacked. +float TimerPreviousHit02 = 0.0 ;Used to approximately detect when he's been 'cornered' so he can escape. +float TimerPreviousHit03 = 0.0 +float TimerPreviousHit04 = 0.0 +float TimerPreviousHit05 = 0.0 +float TimerPreviousHit06 = 0.0 +float TimerOfRecord = 0.0 ;Timer used to determine when Miraak was cornered. +float minTimebetweenSprints = 10.0 +float lastSprintTime = 0.0 +bool sprintBusy = false + +ObjectReference Property MQ06MiraakDeathTeleportMarker Auto diff --git a/source/scripts/dlc2mq06script.psc b/source/scripts/dlc2mq06script.psc new file mode 100644 index 00000000..cd3cda4d --- /dev/null +++ b/source/scripts/dlc2mq06script.psc @@ -0,0 +1,72 @@ +Scriptname DLC2MQ06Script extends Quest Conditional + +event OnUpdate() +; debug.trace(self + " IsWordUnlocked(DLC2BendToWillWord1) = " + Game.IsWordUnlocked(DLC2BendToWillWord1)) +; debug.trace(self + " IsWordUnlocked(DLC2BendToWillWord2) = " + Game.IsWordUnlocked(DLC2BendToWillWord2)) +; debug.trace(self + " IsWordUnlocked(DLC2BendToWillWord3) = " + Game.IsWordUnlocked(DLC2BendToWillWord3)) + + ; watch for player to unlock words + if Game.IsWordUnlocked(DLC2BendToWillWord1) && Game.IsWordUnlocked(DLC2BendToWillWord2) && Game.IsWordUnlocked(DLC2BendToWillWord3) + SetStage(100) + else + RegisterForSingleUpdate(5.0) + endif +endEvent + +; this function clears the "mind control" state of all the pillars +function ClearMindControl() + DLC2PillarBuildSandboxMarkerTOGGLEBeast.Disable() + DLC2PillarBuildSandboxMarkerTOGGLEEarth.Disable() + DLC2PillarBuildSandboxMarkerTOGGLESun.Disable() + DLC2PillarBuildSandboxMarkerTOGGLEWater.Disable() + DLC2PillarBuildSandboxMarkerTOGGLEWind.Disable() + ; mark Tree Stone freed + DLC2StandingStoneTreeREF.Freed = true +endFunction + +Function EnableHM(bool enabling) + if (enabling) + DLC2MQ06HermaeusMoraENDFXRef.ChangeState() + HermaeusMoraTA.Enable() + else + DLC2MQ06HermaeusMoraENDFXRef.ChangeState(false) + HermaeusMoraTA.Disable() + endif +EndFunction + +Function EnableHMBattle(bool enabling, int iNewState = -1) + if (enabling) + DLC2MQ06HermaeusMoraBattleFXRef.ChangeState(true, iNewState) + else + DLC2MQ06HermaeusMoraBattleFXRef.ChangeState(false) + endif +EndFunction + +; called by dragon alias script if dragon unloads after being tamed (so he can't fly) but before player rides him +function MoveTameDragonFailsafe(Actor dragon) + +endFunction + + +WordOfPower Property DLC2BendToWillWord1 Auto +WordOfPower Property DLC2BendToWillWord2 Auto +WordOfPower Property DLC2BendToWillWord3 Auto + +Location Property DLC2Book01DungeonLocation Auto +Location Property DLC2ApocrypaMiraaksTowerLocation Auto + +ObjectReference Property DLC2PillarBuildSandboxMarkerTOGGLEBeast Auto +ObjectReference Property DLC2PillarBuildSandboxMarkerTOGGLEEarth Auto +ObjectReference Property DLC2PillarBuildSandboxMarkerTOGGLESun Auto +ObjectReference Property DLC2PillarBuildSandboxMarkerTOGGLEWater Auto +ObjectReference Property DLC2PillarBuildSandboxMarkerTOGGLEWind Auto + +ObjectReference Property HermaeusMoraTA auto + +int Property MiraakDragonsKilled Auto Conditional +DLC2StandingStoneScript Property DLC2StandingStoneTreeREF Auto + +DLC2HermaeusMoraFaceFXSCRIPT Property DLC2MQ06HermaeusMoraENDFXRef Auto + +DLC2MQ05HermaeusMoraFXScript Property DLC2MQ06HermaeusMoraBattleFXRef Auto + diff --git a/source/scripts/dlc2mqbosstentaclecontroller.psc b/source/scripts/dlc2mqbosstentaclecontroller.psc new file mode 100644 index 00000000..dcc2947d --- /dev/null +++ b/source/scripts/dlc2mqbosstentaclecontroller.psc @@ -0,0 +1,193 @@ +ScriptName DLC2MQBossTentacleController extends objectReference + + +ObjectReference property DLC2MQBossTentacleChainStart001 auto +ObjectReference property DLC2MQBossTentacleChainStart002 auto +ObjectReference property DLC2MQBossTentacleChainStart003 auto +ObjectReference property DLC2MQBossTentacleChainStart004 auto +ObjectReference property DLC2MQBossTentacleChainStart005 auto +ObjectReference property DLC2MQBossTentacleChainStart006 auto +ObjectReference property DLC2MQBossTentacleChainStartCenter auto +ObjectReference property DLC2MQBossTentacleChainEnd001 auto +ObjectReference property DLC2MQBossTentacleChainEnd002 auto +ObjectReference property DLC2MQBossTentacleChainEnd003 auto +ObjectReference property DLC2MQBossTentacleChainEnd004 auto +ObjectReference property DLC2MQBossTentacleChainEnd005 auto +ObjectReference property DLC2MQBossTentacleChainEnd006 auto +ObjectReference property DLC2MQBossTentacleChainEndCenter auto + +bool property fullSweep auto hidden +int property targetArea = 0 auto hidden +bool property clockwise = false auto hidden +float property attackTimer = 0.5 auto hidden + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; State Block +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;This is the state where we are ready to go +auto State waiting + event OnUpdate() +; debug.Trace(self + ": Has recieved OnUpdate") + goToState("Busy") + if fullSweep +; debug.Trace(self + ": Should Trigger Full Sweep") + fullSweep = false + AttackWithFullSweep() + else;if targetArea != 0 +; debug.Trace(self + ": Should Trigger Target Area") + AttackTargetArea() + endif + endEvent +endState + +;Override the functions so we do nothing else +state Busy + event OnUpdate() + endEvent +endState + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Function Block +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +Function AttackWithFullSweep() +; debug.Trace(self + ": Starting AttackWithFullSweep") + objectReference currentLink + if !clockwise + DLC2MQBossTentacleChainStart001.Activate(DLC2MQBossTentacleChainStart001) + utility.Wait(attackTimer) + currentLink = DLC2MQBossTentacleChainStart001.getLinkedRef() + while currentLink + currentLink.Activate(currentLink) + currentLink = currentLink.getLinkedRef() + utility.Wait(attackTimer) + endWhile + DLC2MQBossTentacleChainStart002.Activate(DLC2MQBossTentacleChainStart002) + utility.Wait(attackTimer) + currentLink = DLC2MQBossTentacleChainStart002.getLinkedRef() + while currentLink + currentLink.Activate(currentLink) + currentLink = currentLink.getLinkedRef() + utility.Wait(attackTimer) + endWhile + DLC2MQBossTentacleChainStart003.Activate(DLC2MQBossTentacleChainStart003) + utility.Wait(attackTimer) + currentLink = DLC2MQBossTentacleChainStart003.getLinkedRef() + while currentLink + currentLink.Activate(currentLink) + currentLink = currentLink.getLinkedRef() + utility.Wait(attackTimer) + endWhile + DLC2MQBossTentacleChainStart004.Activate(DLC2MQBossTentacleChainStart004) + utility.Wait(attackTimer) + currentLink = DLC2MQBossTentacleChainStart004.getLinkedRef() + while currentLink + currentLink.Activate(currentLink) + currentLink = currentLink.getLinkedRef() + utility.Wait(attackTimer) + endWhile + DLC2MQBossTentacleChainStart005.Activate(DLC2MQBossTentacleChainStart005) + utility.Wait(attackTimer) + currentLink = DLC2MQBossTentacleChainStart005.getLinkedRef() + while currentLink + currentLink.Activate(currentLink) + currentLink = currentLink.getLinkedRef() + utility.Wait(attackTimer) + endWhile + DLC2MQBossTentacleChainStart006.Activate(DLC2MQBossTentacleChainStart006) + utility.Wait(attackTimer) + currentLink = DLC2MQBossTentacleChainStart006.getLinkedRef() + while currentLink + currentLink.Activate(currentLink) + currentLink = currentLink.getLinkedRef() + utility.Wait(attackTimer) + endWhile + else ;clockwise is true + ;;;;;;;;;;;;;;;;;;NEED to do other attack here + endif + goToState("Waiting") +endFunction + + + +Function AttackTargetArea() +; debug.Trace(self + ": Starting AttackTargetArea") + objectReference currentLink + if !clockwise + if targetArea == 0 + DLC2MQBossTentacleChainStartCenter.Activate(self) + utility.Wait(attackTimer) + currentLink = DLC2MQBossTentacleChainStartCenter.getLinkedRef() + while currentLink + currentLink.Activate(self) + currentLink = currentLink.getLinkedRef() + utility.Wait(attackTimer) + endWhile + elseif targetArea == 1 + DLC2MQBossTentacleChainStart001.Activate(self) + utility.Wait(attackTimer) + currentLink = DLC2MQBossTentacleChainStart001.getLinkedRef() + while currentLink + currentLink.Activate(self) + currentLink = currentLink.getLinkedRef() + utility.Wait(attackTimer) + endWhile + elseif targetArea == 2 + DLC2MQBossTentacleChainStart002.Activate(self) + utility.Wait(attackTimer) + currentLink = DLC2MQBossTentacleChainStart002.getLinkedRef() + while currentLink + currentLink.Activate(self) + currentLink = currentLink.getLinkedRef() + utility.Wait(attackTimer) + endWhile + elseif targetArea == 3 + DLC2MQBossTentacleChainStart003.Activate(self) + utility.Wait(attackTimer) + currentLink = DLC2MQBossTentacleChainStart003.getLinkedRef() + while currentLink + currentLink.Activate(self) + currentLink = currentLink.getLinkedRef() + utility.Wait(attackTimer) + endWhile + elseif targetArea == 4 + DLC2MQBossTentacleChainStart004.Activate(self) + utility.Wait(attackTimer) + currentLink = DLC2MQBossTentacleChainStart004.getLinkedRef() + while currentLink + currentLink.Activate(self) + currentLink = currentLink.getLinkedRef() + utility.Wait(attackTimer) + endWhile + elseif targetArea == 5 + DLC2MQBossTentacleChainStart005.Activate(self) + utility.Wait(attackTimer) + currentLink = DLC2MQBossTentacleChainStart005.getLinkedRef() + while currentLink + currentLink.Activate(self) + currentLink = currentLink.getLinkedRef() + utility.Wait(attackTimer) + endWhile + elseif targetArea == 6 + DLC2MQBossTentacleChainStart006.Activate(self) + utility.Wait(attackTimer) + currentLink = DLC2MQBossTentacleChainStart006.getLinkedRef() + while currentLink + currentLink.Activate(self) + currentLink = currentLink.getLinkedRef() + utility.Wait(attackTimer) + endWhile + else +; debug.Trace(self + ": attackTargetArea triggered with area 0") + endif + else ;clockwise is true + ;;;;;;;;;;;;;;;;;;NEED to do other attack here + endif + targetArea = 0 + goToState("Waiting") +endFunction + + + diff --git a/source/scripts/dlc2soulstealscript.psc b/source/scripts/dlc2soulstealscript.psc new file mode 100644 index 00000000..f812bb29 --- /dev/null +++ b/source/scripts/dlc2soulstealscript.psc @@ -0,0 +1,208 @@ +Scriptname DLC2SoulStealScript extends Quest conditional +{Script attached to DLC2SoulSteal quest} + +ReferenceAlias Property Player auto +ReferenceAlias Property Miraak auto +ReferenceAlias Property Dragon auto + +Scene Property DLC2SoulStealScene auto + +Message Property DLC2SoulStealMsg auto + +MQKillDragonScript Property MQKillDragon auto + +quest property DLC2MQ02 auto +quest Property DLC2MQ06 auto + +MQGreybeardAbsorbScript property MQ105 auto + +bool Property TestMiraak auto ;if true, then ShouldMiraakAppear() always returns true +{If true, he always appears when player kills a dragon} + +GlobalVariable Property DLC2SoulStealCount auto ;if miraak steals soul this goes up one, goes back down if player takes it back + +bool fightPlayer conditional ;while this is true he will fight the player before disappearing, when this is false, he will disappear when done straling soul + +bool MiraakStoleSoul conditional ;scene got to the point where Miraak started to steal the soul + +int secondsBeforeGivingUp = 120 ;houw many seconds until we give up if Miraak hasn't started absorbing the soul + +bool apprearedOnce + +WordOfPower Property DLC2BendToWillWord1 auto + +bool MiraakMadeHisIntroduction +quest property DLC2MQ01 auto +quest Property MQ104 auto + +Faction Property MQNoDragonAbsorb auto + +; for Greybeard effect +VisualEffect Property FXGreybeardAbsorbEffect Auto +EffectShader Property GreybeardPowerAbsorbFXS Auto +EffectShader Property GreybeardPlayerPowerAbsorbFXS Auto +sound property NPCDragonDeathSequenceWind auto +sound property NPCDragonDeathSequenceExplosion auto + + + +Event OnUpdate() +; Debug.Trace(self + "OnUpdate()") + if MiraakStoleSoul == false + DLC2SoulStealScene.Stop() + endif +EndEvent + +Function StartTimer() +; Debug.Trace(self + "StartTimer()") + RegisterForSingleUpdate(secondsBeforeGivingUp) +EndFunction + +Function EndTimer() + unregisterForUpdate() +; Debug.Trace(self + "EndTimer()") +EndFunction + +bool Function TryMiraakMakeHisIntroduction(Actor DragonRef) + + bool returnVar = false + +; Debug.Trace(self + "TryMiraakMakeHisIntroduction() -- ALWAYS RETURNS FALSE NOW") + +; if MiraakMadeHisIntroduction == false && MQ104.GetStage() >=150 && Game.GetPlayer().IsInCombat() == false && DragonRef.isInFaction(MQNoDragonAbsorb) == false +; MiraakMadeHisIntroduction = true +; returnVar = true +; Debug.Trace(self + "TryMiraakMakeHisIntroduction() Miraak is going to make his introductory appearance, calling setStage 0 on DLC2MQ01") +; DLC2MQ01.SetStage(0) +; endif +; +; Debug.Trace(self + "TryMiraakMakeHisIntroduction() returning: " + returnVar) + + RETURN returnVar + +EndFunction + +bool Function ShouldMiraakAppear(Actor DragonRef) +; Debug.Trace(self + "ShouldMiraakAppear() checking quest stages and other logic") + + bool returnVar = false + int chanceToAppear = 25 + + if DLC2MQ02.GetStage() >= 200 && DLC2MQ06.GetStage() < 500 && DragonRef.isInFaction(MQNoDragonAbsorb) == false + if Game.IsWordUnlocked(DLC2BendToWillWord1) || Game.GetPlayer().GetActorValue("DragonSouls") > 0 + if Utility.RandomInt(1,100) <= chanceToAppear || apprearedOnce == false + apprearedOnce = true + returnVar = true + endif + endif + endif + + if TestMiraak == true +; Debug.Trace(self + "ShouldMiraakAppear() -- TestMiraak == true, so forcing returnVar to true") + returnVar = true + endif + +; Debug.Trace(self + "ShouldMiraakAppear() returning: " + returnVar) + return returnVar + +EndFunction + +Function MiraakAppears(ObjectReference DragonRef) +; Debug.Trace(self + "MiraakAppears()" + DragonRef) + Dragon.ForceRefTo(DragonRef) + + DLC2MiraakScript MiraakRef = Miraak.GetReference() as DLC2MiraakScript + MiraakRef.AppearAtRef = DragonRef + MiraakRef.Appear() + MiraakRef.SetNoBleedoutRecovery(true) + + ;clear tracking variables from previous incarnations + fightPlayer = false + MiraakStoleSoul = false + + ;START THE "TIMER" + StartTimer() + + DLC2SoulStealScene.start() + +EndFunction + +Function MiraakDisappears() +; Debug.Trace(self + "MiraakDisappears()") + DLC2MiraakScript MiraakRef = Miraak.GetReference() as DLC2MiraakScript + MiraakRef.Disappear() + MiraakRef.SetNoBleedoutRecovery(false) + MiraakRef.RestoreAV("Health", 999999999) + + ;if Miraak disappears before he stole the soul, put the dragon back in the state that lets the player steal it's soul + if MiraakStoleSoul == false + (Dragon.GetActorReference() as DragonActorScript).gotoState("deadAndWaiting") + endif + +EndFunction + +Function StealSoul() + EndTimer() +; Debug.Trace(self + "StealSoul()") + MiraakStoleSoul = true + ModDLC2SoulStealCount(1) + MQKillDragon.DeathSequence(Dragon.GetActorReference(), Miraak.GetActorReference()) +EndFunction + +Function FinishStealingSoul() +; Debug.Trace(self + "FinishStealingSoul()") + DLC2SoulStealMsg.show() +EndFunction + +Function PlayerAttackedMiraak() + EndTimer() +; Debug.Trace(self + "PlayerAttackedMiraak()") + fightPlayer = true + +EndFunction + +Function PlayerTakesSoulBack() +; Debug.Trace(self + "PlayerTakesSoulBack()") + utility.wait(1) + AbsorbSoulFromMiraak(Miraak.GetActorReference()) + Game.GetPlayer().modActorValue("dragonsouls", 1) + ModDLC2SoulStealCount(-1) +EndFunction + +Function ModDLC2SoulStealCount(int amountToMod) +; Debug.Trace(self + "ModDLC2SoulStealCount()") + DLC2SoulStealCount.setValue(DLC2SoulStealCount.GetValue() + amountToMod) +EndFunction + +Function MiraakDetached() +; Debug.Trace(self + "MiraakDetached()") + if DLC2SoulStealScene.IsPlaying() +; Debug.Trace(self + "MiraakDetached() DLC2SoulStealScene is playing, calling stop()") + DLC2SoulStealScene.Stop() + endif +EndFunction + + +;CRIBBED FROM MQGreybeardAbsorbScript "AbsorbSoul()" +function AbsorbSoulFromMiraak(Actor target) +; Debug.Trace(self + "AbsorbSoulFromMiraak()") + + Actor PlayerRef = Game.GetPlayer() + + ;Play art and fx shaders on player and targeted grybeard + FXGreybeardAbsorbEffect.Play(target, 7, PlayerRef) + GreybeardPowerAbsorbFXS.Play(target) + GreybeardPlayerPowerAbsorbFXS.Play(PlayerRef) + + ; Sounds for when the wispy particles being to fly at the player. + NPCDragonDeathSequenceWind.play(target) + NPCDragonDeathSequenceExplosion.play(target) + + utility.wait(7) + + ;remove magic shaders + GreybeardPowerAbsorbFXS.Stop(target) + GreybeardPlayerPowerAbsorbFXS.Stop(PlayerRef) + +EndFunction + diff --git a/source/scripts/dlc2standingstonescript.psc b/source/scripts/dlc2standingstonescript.psc new file mode 100644 index 00000000..7f2604f1 --- /dev/null +++ b/source/scripts/dlc2standingstonescript.psc @@ -0,0 +1,112 @@ +Scriptname DLC2StandingStoneScript extends ObjectReference + +PROJECTILE Property DLC2VoicePushProjectile01 Auto +PROJECTILE Property DLC2VoicePushProjectile03 Auto +SPELL Property DLC2SpellLearned Auto +bool property Freed auto hidden +float DelayReady + +auto State Waiting + +Event OnActivate(ObjectReference akActionRef) + gotoState("Busy") +; debug.Trace("STANDING STONE: I've been touched") + if akActionRef == game.GetPlayer() + if Freed == true +; debug.Trace("STANDING STONE: has been freed - DelayReady: " + DelayReady + ", GameDays: " + GameDaysPassed.GetValue()) + if GameDaysPassed.GetValue() > DelayReady && game.GetPlayer().HasSpell(DLC2SpellLearned) == false +; debug.Trace("STANDINGSTONE: it's been a day since the spell was last added") + DelayReady = GameDaysPassed.GetValue() + 0.75 + PlayAnimation("stage3") + DLC2StoneActivateSound.play(self) + (akActionRef as actor).AddSpell(DLC2SpellLearned, true) +; debug.Trace("STANDINGSTONE: DLC2SacredStoneSpell" + DLC2SacredStoneSpell) + DLC2SacredStoneSpell.Cast(akActionRef) + else + DLC2StandingStoneNotReadyMsg.Show() + endif + else + WorkOnPillar(false) + endif + else + if Freed == false && (akActionRef as Actor) + WorkOnPillarNPC(akActionRef as Actor) + endif + endif + gotoState("Waiting") +EndEvent + +endState + +State Busy + ; do nothing +EndState + +function WorkOnPillarNPC(Actor pillarNPC) + ; put into alias + FollowerAtPillar.ForceRefTo(pillarNPC) + ; clear favor state + pillarNPC.SetDoingFavor(false) + ; work on pillar scene + DLC2PillarFollowerScene.Start() +endFunction + +function WorkOnPillar(bool bSleepMove = true) + if GetLinkedRef() + ; player blacks out, wakes up working on pillar + Game.DisablePlayerControls() + if bSleepMove == false + FadeToBlackImod.Apply() + MAGStandingStoneActivateA.Play(Game.GetPlayer()) + utility.wait(2) + FadeToBlackImod.PopTo(FadeToBlackHoldImod) + else + FadeToBlackImod.PopTo(FadeToBlackHoldImod) + utility.wait(2) + endif + Game.ForceThirdPerson() + ; put player in furniture + Game.GetPlayer().MoveTo(GetLinkedRef()) + DLC2PillarMiraakVoice.Start() + utility.wait(2) + FadeToBlackHoldImod.PopTo(FadeToBlackBackImod) + FadeToBlackHoldImod.Remove() + MAGStandingStoneActivateB.Play(Game.GetPlayer()) + utility.wait(2) +; debug.trace(self + " enabling controls") + Game.EnablePlayerControls() + while GetLinkedRef().IsFurnitureInUse() + utility.wait(1.0) + endWhile + DLC2PillarMiraakVoice.Stop() + DLC2Pillar.SetStage(100) ; runs Neloth scene, tracks player having touched pillar once + endif + +endFunction + + +ImageSpaceModifier Property FadeToBlackImod Auto + +ImageSpaceModifier Property FadeToBlackHoldImod Auto + +ImageSpaceModifier Property FadeToBlackBackImod Auto + +Topic Property DLC2PillarBlockingTopic Auto + +Scene Property DLC2PillarMiraakVoice Auto + +Quest Property DLC2Pillar Auto + +GlobalVariable Property GameDaysPassed Auto + +Message Property DLC2StandingStoneNotReadyMsg Auto + +Scene Property DLC2PillarFollowerScene Auto +ReferenceAlias Property FollowerAtPillar Auto + +Sound Property MAGStandingStoneActivateA Auto +Sound Property MAGStandingStoneActivateB Auto + +SPELL Property DLC2SacredStoneSpell Auto + +Sound Property DLC2StoneActivateSound Auto diff --git a/source/scripts/dlc2tamedragonscript.psc b/source/scripts/dlc2tamedragonscript.psc new file mode 100644 index 00000000..75927a91 --- /dev/null +++ b/source/scripts/dlc2tamedragonscript.psc @@ -0,0 +1,330 @@ +Scriptname DLC2TameDragonScript extends Quest Conditional + +bool bAllowRestrain = false ; this gets set to true at the start of Tame sequence, false during EndWait to prevent accidentally rerestraining him + +function TameDragon(actor newDragon) +; debug.trace(self + " TameDragon START") + ; if alias already has something in it (that's alive), do nothing + if dragonReleasedAlias.GetRef() && !dragonReleasedAlias.GetActorRef().IsDead() + ; do nothing, dragon is in the process of being released +; debug.trace(self + " TameDragon: time's up, do nothing") + ; if this is not the current target, give a message +; if dragonReleasedAlias.GetRef() != newDragon + DLC2TameDragonResistMSG.Show() +; endif + return + elseif DragonAlias.GetRef() && !dragonAlias.GetActorRef().IsDead() + ; if we're hitting a tamed dragon again, tell him to land + ; otherwise, do nothing (can't tame 2 dragons at once) + if DragonAlias.GetActorRef() == newDragon && newDragon.GetActorValue("variable01") != 99 + ; we're hitting an already tamed dragon with tame again - tell him to land + LandDragon() + else + ; show "resists" message + DLC2TameDragonResistMSG.Show() + endif + ; no matter what - don't do anything else + return + endif +; debug.trace(self + " TameDragon: trying to tame...") + ; if dragon is not in an interior, then check if it's in an allowed worldspace - if not, do nothing + if !newDragon.IsInInterior() && !DLC2TameDragonAllowedWorldspaces.HasForm(newDragon.GetWorldSpace()) +; debug.trace(self + " TameDragon: dragon is in invalid worldspace + " + newDragon.GetWorldSpace() + ", do nothing") + return + endif + + ; reset allow restrain flag + bAllowRestrain = true + + ; move orbit marker to player's position + DLC2TameDragonOrbitMarker.Moveto(Game.GetPlayer()) + + ; always hold him on the ground to start + ; give "no fly" ability so it doesn't interfere with scripted "no fly" + newDragon.AddSpell(DLC2TameDragonNoFlyAbility) + + ; put dragon in alias + DragonAlias.ForceRefTo(newDragon) + ; stop combat + newDragon.StopCombatAlarm() + + ; start scene + ; check for special case: MQ06 + if newDragon.IsInFaction(DLC2MQ06DragonFaction) && DLC2MQ06.GetStage() >= 10 && DLC2MQ06.GetStage() < 300 + ; this is the MQ06 dragon - first time tamed + bMQ06DragonTaming = true + DLC2MQ06TameDragonScene.Start() + else + bMQ06DragonTaming = false + DLC2TameDragonScene1.Start() + endif + + ; heal the dragon + newDragon.RestoreActorValue("Health", 9999) +endFunction + +; call this function to get the dragon to briefly land next to the player +function LandDragon() +; debug.trace(self + " LandDragon: dragon " + dragonAlias.GetRef() + " landing again") + Actor dragonActor = dragonAlias.GetActorRef() + ; reset actor value + if dragonActor.GetActorValue("variable01") != 99 + dragonActor.SetActorValue("Variable01", 0) + else + return + endif + + ; move orbit marker to player's position + DLC2TameDragonOrbitMarker.Moveto(Game.GetPlayer()) + + ; always hold him on the ground to start + ; give "no fly" ability so it doesn't interfere with scripted "no fly" + dragonActor.AddSpell(DLC2TameDragonNoFlyAbility) + + ; start scene + DLC2TameDragonScene2.Start() +endFunction + +; check if dragon is in valid worldspace - if not, release immediately +function ValidateWorldspace() +; debug.trace(self + " ValidateWorldspace") + if DLC2TameDragonAllowedWorldspaces.HasForm(Game.GetPlayer().GetWorldSpace()) == false +; debug.trace(self + " player in invalid worldspace " + Game.GetPlayer().GetWorldSpace() + " - release dragon") + EndWait() + ReleaseDragon() + endif + +endFunction + +; call this when initial scene is ended or player tries to ride him +function EndWait() +; debug.trace(self + " EndWait") + Actor dragonActor = dragonAlias.GetActorRef() + + ; if he's not in a "waiting" state, do nothing + if dragonActor.HasSpell(DLC2TameDragonNoFlyAbility) == false +; debug.trace(self + " EndWait: not in waiting state, do nothing") + return + endif + + ; can't restrain him again + bAllowRestrain = false + ; unrestrain him + RestrainDragon(false) + ; set crime faction + dragonActor.SetCrimeFaction(DLC2TameDragonFaction) + + ; let him fly if allowed + dragonActor.RemoveSpell(DLC2TameDragonNoFlyAbility) + dragonActor.RemoveSpell(DLC2abCalmDragon) + + ; safety check: if dragon is not in aliases, must have been released (probably by player aggroing it) + if dragonAlias.GetActorRef() != dragonActor +; debug.trace(" EndWait - dragonAlias doesn't match, do nothing else") + return + endif + + ; set "done waiting" variable + if dragonActor.GetActorValue("variable01") == 0 + dragonActor.SetActorValue("variable01", 1) + endif + + dragonActor.EvaluatePackage() + ; register for summon duration (not for MQ06 dragon) + if !bMQ06DragonTaming + RegisterForSingleUpdateGameTime(fTameHours) + endif + + ; try adding the calm again in case it didn't work the first time +; debug.trace(self + " adding DLC2abCalmDragon to dragon") + dragonActor.AddSpell(DLC2abCalmDragon) + utility.wait(2) + dragonActor.RemoveSpell(DLC2abCalmDragon) + + ; if player is riding, increment riding variable + if dragonActor.IsBeingRidden() + if iDragonsRiddenCount == 0 + RegisterForSingleUpdate(8.0) + endif + ; only increment if not already in tamed faction + if !dragonActor.IsInFaction(DLC2TamedDragonTrackingFaction) + dragonActor.AddToFaction(DLC2TamedDragonTrackingFaction) + iDragonsRiddenCount = iDragonsRiddenCount + 1 + if iDragonsRiddenCount >= iDragonsRiddenAchievementCount + Game.AddAchievement(73) + endif + endif + endif +endFunction + +; call this when timer runs out or dragon dies +function ReleaseDragon() +; debug.trace(self + " ReleaseDragon") + ; set actor value to indicate he wants to be released when possible + Actor dragonActor = dragonAlias.GetActorRef() + ; don't do this more than once to the same dragon + if dragonActor.GetActorValue("variable01") != 99 + dragonActor.SetActorValue("variable01", 99) + ; try to dispel now or later + TryToReleaseDragon(dragonActor) + endif +endFunction + +event OnUpdateGameTime() +; debug.trace(self + " OnUpdate") + ; is dragon waiting to be released? + Actor dragonActor = dragonAlias.GetActorRef() + if dragonActor.GetActorValue("variable01") == 99 + TryToReleaseDragon(dragonActor) + else + ; time to dispel + ReleaseDragon() + endif +endEvent + +int tempCount = 0 + +function TryToReleaseDragon(actor dragonActor) + tempCount += 1 +; debug.trace(self + " TryToReleaseDragon " + tempCount) + + ; if player is not riding, release + if dragonActor.IsBeingRidden() == 0 + ; RELEASE: + dragonActor.SetRestrained(false) ; just in case + dragonAlias.Clear() + dragonReleasedAlias.ForceRefTo(dragonActor) + ; if in combat with player, release immediately + if dragonActor.IsHostileToActor(Game.GetPlayer()) +; debug.trace(self + " hostile to player, release immediately") + FinishRelease() + else +; debug.trace(self + " normal release, fly away before releasing") + ; move into "released" alias (no riding allowed) + DLC2TameDragonReleaseScene.Start() + endif + else + ; player is riding - need him to land + ; FOR NOW - no time limit if player is riding + ; just keep checking for player to be not riding + +; dragonActor.SetAllowFlyingEx(false, false, true) + +; if dragonActor.GetFlyingState() == 0 && dragonActor.IsBeingRidden() == 1 && Game.GetPlayer().IsOnMount() == 1 + ; force player to dismount +; Game.GetPlayer().Dismount() + ; give time for dismount to finish +; RegisterForSingleUpdateGameTime(0.1) +; else + RegisterForSingleUpdateGameTime(0.1) +; endif + endif +endFunction + +; called when escape scene ends +function FinishRelease() + actor dragonActor = dragonReleasedAlias.GetActorRef() +; debug.trace(" FinishRelease: dragon=" + dragonActor) + ; clear actor value + dragonActor.SetActorValue("variable01", 0) +; debug.trace(self + " FinishRelease - variable01=" + dragonactor.GetActorValue("variable01")) + ; failsafe + dragonActor.RemoveSpell(DLC2TameDragonNoFlyAbility) + ; clear aliases + dragonAlias.Clear() + dragonReleasedAlias.Clear() + ; not teammate any more +; debug.trace(self + " FinishRelease - dragon NOT teammate") + dragonActor.SetPlayerTeammate(false) + dragonActor.SetCrimeFaction(none) + dragonActor.EvaluatePackage() +endFunction + +function DragonDead() + ; called by OnDeath block on dragon + ; stop pending updates if any + UnregisterForUpdateGameTime() +endFunction + +function RestrainDragon(bool bRestrain) + ; this is to prevent him from responding to attacks when on the ground + ; only do this when not flying! + actor dragonActor = dragonAlias.GetActorRef() + if bRestrain && dragonActor.GetActorValue("variable01") != 99 + while dragonActor.GetFlyingState() > 0 && bAllowRestrain + utility.wait(1.0) + endwhile +; debug.trace(self + " ready to restrain dragon") + ; only restrain if the allow flag is still true + if bAllowRestrain +; debug.trace(self + " restraining dragon") + dragonActor.SetRestrained(true) + ; stop combat/alarms again to be sure + dragonActor.StopCombatAlarm() + ; add calm ability - has to be AFTER restraining him +; debug.trace(self + " adding DLC2abCalmDragon to dragon") + dragonActor.AddSpell(DLC2abCalmDragon) + endif + ; TRY MAKING TEAMMATE here - do it even if restrain can't happen + dragonActor.SetPlayerTeammate(true, false) + else +; debug.trace(self + " UN-Restraining dragon") + dragonActor.SetRestrained(false) + endif +endFunction + +; this is used only for displaying the first-time help message +bool bLearnMessageDisplayed = false +event OnUpdate() + if !bLearnMessageDisplayed + bLearnMessageDisplayed = true + DLC2LearnDragonRidingMsg.Show() + endif +endEvent + + +ReferenceAlias Property dragonAlias Auto +ReferenceAlias Property dragonReleasedAlias Auto + +Scene Property DLC2TameDragonScene1 Auto +{ normal tame scene to hold dragon on ground when you first tame him} + +Scene Property DLC2TameDragonScene2 Auto +{ tame scene to hold dragon on ground after already tamed, if hit by the spell again } + +Scene Property DLC2MQ06TameDragonScene Auto +{ MQ06 tame dragon scene } + +Faction Property DLC2MQ06DragonFaction Auto +{ used to check for MQ06 dragon } + +Quest Property DLC2MQ06 Auto + +Float Property fTameHours = 1.0 Auto Conditional +{duration of tame in game hours} + +Scene Property DLC2TameDragonReleaseScene Auto + +ObjectReference Property DLC2TameDragonOrbitMarker Auto +{ default object that the orbit package uses + code also moves this to fast travel destination } + +FormList Property DLC2TameDragonAllowedWorldspaces Auto +{ formlist of allowed worldspaces - dragon can only be tamed/ridden in these worldspaces } + +bool bMQ06DragonTaming ; set to true when we've tamed the MQ06 dragon first time + +SPELL Property DLC2TameDragonNoFlyAbility Auto + +SPELL Property DLC2abCalmDragon Auto + +Faction Property DLC2TameDragonFaction Auto + +Message Property DLC2TameDragonResistMSG Auto + +int Property iDragonsRiddenAchievementCount = 5 Auto +int iDragonsRiddenCount = 0 + +Message Property DLC2LearnDragonRidingMsg Auto + +Faction Property DLC2TamedDragonTrackingFaction Auto diff --git a/source/scripts/doorbar.psc b/source/scripts/doorbar.psc new file mode 100644 index 00000000..ac3c06ed --- /dev/null +++ b/source/scripts/doorbar.psc @@ -0,0 +1,104 @@ +scriptName doorBar extends objectReference +{script lives on objects that bar a door from one side} + +;======================================================================================; +; PROPERTIES / +;=============/ +bool property startOpen = false auto +{Start open? Default: false} +message property BarredMSG auto +{set the "door is barred from the other side" message here"} +keyword Property BarredDoorNavCutKeyword auto +{keyword for the NavCut collision linked ref} + +;Only do the onCellLoad block once per reset. +bool initialized = false + +;======================================================================================; +; VARIABLES / +;=============/ +; store the door I am barring +objectReference myLink +objectReference myNavCutLink +; need to control the script on companion door +barredDoor doorScript + +;======================================================================================; +; EVENTS / +;=============/ +EVENT onCellLoad() + myLink = self.getLinkedRef() + myNavCutLink = self.getLinkedRef(BarredDoorNavCutKeyword) + doorScript = myLink as barredDoor +; Debug.Trace("Door Bar Load: " + initialized) + if (!initialized) + initialized = True + if startOpen == true + gotostate("down") + onActivate(Self) + else + myLink.blockActivation(true) + gotoState("down") + endif + endif +endEVENT + +STATE down + EVENT onActivate(objectReference actronaut) + doorScript.busy = true + gotoState("busy") + myNavCutLink.Disable() + playAnimationAndWait("up","done") + doorScript.barred = false + myLink.blockActivation(false) + gotoState("up") + doorScript.busy = false + endEVENT + + EVENT SetBarPosition(bool setBarUp) +; ;Debug.Trace("Setting Bar Up") + if (setBarUp) + onActivate(Self) + EndIf + endEVENT +endSTATE + +STATE up +EVENT onActivate(objectReference actronaut) + if myLink.getOpenState() != 3 + ; can't drop a bar when the corresponding door is open + else + doorScript.busy = true + gotoState("busy") + myNavCutLink.Enable() + playAnimationAndWait("down","done") + doorScript.barred = true + myLink.blockActivation(true) + gotoState("down") + doorScript.busy = false + endif + endEVENT + + EVENT SetBarPosition(bool setBarUp) + if (!setBarUp) + if (myLink.getOpenState() == 1) + myLink.Activate(Self) + Utility.Wait(0.5) + SetBarPosition(setBarUp) + ElseIf (myLink.getOpenState() == 2 || myLink.getOpenState() == 4) + Utility.Wait(0.5) + SetBarPosition(setBarUp) + Else + onActivate(Self) + EndIf + EndIf + endEVENT +endSTATE + +STATE busy + ; allow nothing here. +endSTATE + +EVENT SetBarPosition(bool setBarUp) + ;Until we're in either the Up or Down position, don't do anything. +endEVENT diff --git a/source/scripts/dragonperchscript.psc b/source/scripts/dragonperchscript.psc new file mode 100644 index 00000000..d48a2cbc --- /dev/null +++ b/source/scripts/dragonperchscript.psc @@ -0,0 +1,19 @@ +Scriptname DragonPerchScript extends ObjectReference +{Script attached to all dragon perches. ASSUMES THE ONLY THING ABLE TO ACTIVATE THE PERCH IS A DRAGON!} + +WIFunctionsScript Property WI Auto ;added by jduvall +{Pointer to WIFunctionsScript on WI quest.} + +;Primary use at the moment, is to register a dragon attack on towns, should a dragon perch somewhere in a town -jduvall + +Event OnActivate(ObjectReference akActionRef) + + ;*** !!! ASSUMES THE ONLY THING ABLE TO ACTIVATE THE PERCH IS A DRAGON !!!! *** + +; debug.trace(self + "OnActivate(" + akActionRef + ") calling WI.RegisterDragonAttack()") + + ;SEE ALSO: DragonActorScript + WI.RegisterDragonAttack(GetEditorLocation(), akActionRef as Actor) + + +EndEvent diff --git a/source/scripts/dragonpriestactorscript.psc b/source/scripts/dragonpriestactorscript.psc new file mode 100644 index 00000000..4e64ef35 --- /dev/null +++ b/source/scripts/dragonpriestactorscript.psc @@ -0,0 +1,68 @@ +Scriptname DragonPriestActorScript extends ActiveMagicEffect +{Abilities and FX for Dragon Priest} + +import debug + +armor property DragonPriestArmor01 auto +{Glowing cape and mouth streams armor} +VisualEffect Property DragonPriestParticlesFX Auto +{Floor based stream of upward particles} +VisualEffect Property DragonPriestEyeGlowFX Auto +{eye glow fx} +VisualEffect Property FXfallingSandDragonPriestEffect Auto +{falling sand from holes fx} +Explosion Property FXDragonPriestSmallExplosion Auto +{dust and fabric explosion played on state change} +Explosion Property FXDragonPriestLargeExplosion Auto +{large dust fabric and metal bits explosion played on dying} +Activator property AshPileObject auto +{The object we use as a pile.} +int doOnce = 0 ;Stops on hit from spamming +Actor selfRef ;local pointer to the curren dragon priest + +EVENT OnEffectStart(Actor Target, Actor Caster) + selfRef = caster ;local pointer to the curren dragon priest + if (selfRef.GetSleepState() == 3) +; Debug.Trace("DP is sleeping! 3") + else + ;Play all of the magic fx + selfRef.equipitem(DragonPriestArmor01) + DragonPriestParticlesFX.play(selfRef, -1) + DragonPriestEyeGlowFX.play(selfRef, -1) + endIf +ENDEVENT + + Event OnGetUp(ObjectReference akFurniture) +; Debug.Trace("Dragon preist just got up from " ) + ;Play all of the magic fx + selfRef.equipitem(DragonPriestArmor01) + DragonPriestParticlesFX.play(selfRef, -1) + DragonPriestEyeGlowFX.play(selfRef, -1) + endEvent + +Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + ;When hit incriments and plays the trasition to hirt state fx. Currently plays on the 5th hit. To be redone by design to work on health + doOnce = doOnce + 1 + if doOnce == 5 + selfRef.placeAtMe(FXDragonPriestSmallExplosion, 1) + DragonPriestParticlesFX.Stop(selfRef) + FXfallingSandDragonPriestEffect.play(selfRef, -1) + selfRef.PlaySubGraphAnimation( "stage2" ) + doOnce = doOnce + 1 + endIf +ENDEVENT + +EVENT OnDying(Actor akKiller) + ; play all of the many dying fx and clean up the magic fx + selfRef.placeAtMe(FXDragonPriestLargeExplosion, 1) + selfRef.PlaySubGraphAnimation( "stage3" ) + selfRef.unequipitem(DragonPriestArmor01) + DragonPriestEyeGlowFX.Stop(selfRef) + ;place ash pile + utility.wait(1.0) + selfRef.AttachAshPile(AshPileObject) + utility.wait(2.0) + FXfallingSandDragonPriestEffect.Stop(selfRef) + +ENDEVENT + diff --git a/source/scripts/dragontowerwallscript.psc b/source/scripts/dragontowerwallscript.psc new file mode 100644 index 00000000..4aaeafc6 --- /dev/null +++ b/source/scripts/dragontowerwallscript.psc @@ -0,0 +1,38 @@ +scriptname dragonTowerWallScript extends objectReference + +import debug +import utility +import sound + +Quest property myQuest auto +int property myQuestStage auto +String property myEvent auto +sound property QSTE3TowerHoleMono auto +sound property QSTE3TowerHoleStereo auto +ObjectReference property mySpellOrigin auto +ObjectReference property mySpellTarget01 auto +Spell property mySpell auto + +bool isCasting = false + +;************************************ + +EVENT onLoad() + registerForAnimationEvent(self, myEvent) +endEVENT + +;************************************ + +EVENT onAnimationEvent(ObjectReference akSource, string asEventName) + if (asEventName == myEvent) + myQuest.setStage(myQuestStage) + KnockAreaEffect(1, 1.5*getLength()) + QSTE3TowerHoleMono.play(self) + QSTE3TowerHoleStereo.play(self) + ;need to player spell effect + ;wait(4.75) + ;mySpell.Cast(mySpellOrigin, mySpellTarget01) + endif +endEVENT + +;************************************ \ No newline at end of file diff --git a/source/scripts/dunarcherpressureplatescript.psc b/source/scripts/dunarcherpressureplatescript.psc new file mode 100644 index 00000000..bf7fa4f4 --- /dev/null +++ b/source/scripts/dunarcherpressureplatescript.psc @@ -0,0 +1,227 @@ +scriptName dunArcherPressurePlateScript extends ObjectReference + +import debug +import utility + +Formlist property flArrows auto +int property targetNumber auto +{0=Left Target 1=Middle Target 2=RightTarget 3=FarTarget} + +ObjectReference property LeftTarget auto +ObjectReference property MiddleTarget auto +ObjectReference property RightTarget auto +ObjectReference property FarTarget auto +ObjectReference property myActorTarget auto +Actor property myActor auto +Quest property dunArcherQST auto +dunArcherQuestScript myQuest +bool playerHitTarget +bool correctArrows +bool inBox + +;************************************ + +Event OnLoad() + myQuest = dunArcherQST as dunArcherQuestScript +endEvent + +;************************************ + +auto State Waiting + Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + Actor actorRef = akAggressor as Actor + gotoState("DoNothing") + if(myQuest.getStage() == 30 && myQuest.getStage() <= 32) + myQuest.feedbackFlag = 0 + endif + + activate(self as objectReference) + + if(actorRef == game.GetPlayer()) + ;player hit the target + playerHitTarget = true + endif + + if(flArrows.hasForm(akProjectile)) + ;target was hit with correct arrow + correctArrows = true + endif + + if(myQuest.playerInBox == 1) + ;player is in box when target was hit + inBox = true + endif + + if(playerHitTarget && correctArrows && inBox) + ;player hit target and is using the correct arrows and is in box + if(targetNumber == 0) + ;if player hit left target + if(myQuest.getStage() == 30 || myQuest.getStage() == 32 || myQuest.getStage() == 60) + ;player hit the wrong target + myQuest.feedbackFlag = 4 + else + if(myQuest.getStage() == 31) + ;player hit the left target correctly + myQuest.feedbackFlag = 0 + myQuest.setStage(32) + else + if(myQuest.getStage() == 50 || myQuest.getStage() == 51 || myQuest.getStage() == 70 || myQuest.getStage() == 71) + ;checking for when player needs to hit each of the three targets + myQuest.playerHitTargetLeft = 1 + endif + endif + endif + else + if(targetNumber == 1) + ;if player hit middle target + if(myQuest.getStage() == 30) + ;player hit middle target correctly + myQuest.feedbackFlag = 0 + myQuest.setStage(31) + else + if(myQuest.getStage() == 31 || myQuest.getStage() == 32 || myQuest.getStage() == 60) + ;player hit the wrong target + myQuest.feedbackFlag = 4 + else + if(myQuest.getStage() == 50 || myQuest.getStage() == 51 || myQuest.getStage() == 70 || myQuest.getStage() == 71) + ;checking for when player needs to hit each of the three targets + myQuest.playerHitTargetMiddle = 1 + endif + endif + endif + else + if(targetNumber == 2) + ;player hit right target + if(myQuest.getStage() == 30 || myQuest.getStage() == 31 || myQuest.getStage() == 60) + ;player hit the wrong target + myQuest.feedbackFlag = 4 + else + if(myQuest.getStage() == 32) + ;player hit the right target correctly + myQuest.feedbackFlag = 0 + myQuest.setStage(40) + else + if(myQuest.getStage() == 50 || myQuest.getStage() == 51 || myQuest.getStage() == 70 || myQuest.getStage() == 71) + ;checking for when player needs to hit each of the three targets + myQuest.playerHitTargetRight = 1 + endif + endif + endif + else + if(targetNumber == 3) + ;player hit far target + if(myQuest.getStage() == 30 || myQuest.getStage() == 31 || myQuest.getStage() == 32) + ;player hit the wrong target + myQuest.feedbackFlag = 4 + else + if(myQuest.getStage() == 60) + ;player hit the far target correctly + myQuest.feedbackFlag = 0 + myQuest.playerChallengeComplete01 = 1 + myQuest.setStage(62) + else + if(myQuest.getStage() == 70 || myQuest.getStage() == 71) + ;checking for when player needs to hit all targets + myQuest.playerHitTargetFar = 1 + endif + endif + endif + endif + endif + endif + endif + + else + if(playerHitTarget && correctArrows && !inBox) + ;player hit target, used correct arrows, but is not in box + myQuest.feedbackFlag = 1 + else + if(playerHitTarget && !correctArrows && inBox) + ;player hit target, is in box, but used wrong arrows + myQuest.feedbackFlag = 2 + else + if(playerHitTarget && !correctArrows && !inBox) + ;player hit target, but used wrong arrows and is not in box + myQuest.feedbackFlag = 3 + endif + endif + endif + endif + + + ;this is for angie + if(actorRef == myActor) + if(myQuest.getStage() == 45) + ;Angi is shooting the three targets + if(myQuest.count == 0) + myActorTarget.moveto(LeftTarget) + myQuest.count = 1 + else + if(myQuest.count == 1) + myActorTarget.moveto(RightTarget) + myQuest.count = 2 + else + if(myQuest.count == 2) + myActorTarget.moveto(MiddleTarget) + myQuest.count = 0 + else + myQuest.count = 0 + endif + endif + endif + else + if(myQuest.getStage() == 69) + ;Angi is shooting all four targets + if(myQuest.count == 0) + myActorTarget.moveto(LeftTarget) + myQuest.count = 1 + else + if(myQuest.count == 1) + myActorTarget.moveto(MiddleTarget) + myQuest.count = 2 + else + if(myQuest.count == 2) + myActorTarget.moveto(FarTarget) + myQuest.count = 3 + else + if(myQuest.count == 3) + myActorTarget.moveto(MiddleTarget) + myQuest.count = 0 + endif + endif + endif + endif + endif + endif + endif + + ;reset vars + playerHitTarget = false + correctArrows = false + inBox = false + + + ;for player hitting three targets + if(myQuest.getStage() == 50 || myQuest.getStage() == 51) + if((myQuest.playerHitTargetLeft == 1) && (myQuest.playerHitTargetMiddle == 1) && (myQuest.playerHitTargetRight == 1)) + myQuest.playerChallengeComplete01 = 1 + endif + endif + + if(myQuest.getStage() == 70 || myQuest.getStage() == 71) + if((myQuest.playerHitTargetLeft == 1) && (myQuest.playerHitTargetMiddle == 1) && (myQuest.playerHitTargetRight == 1) && (myQuest.playerHitTargetFar == 1)) + myQuest.playerChallengeComplete01 = 1 + endif + endif + gotoState("Waiting") + endEvent + +endState + +;************************************ + +State DoNothing + ;do nothing +EndState + +;************************************ diff --git a/source/scripts/dunarcherquestscript.psc b/source/scripts/dunarcherquestscript.psc new file mode 100644 index 00000000..603a12e2 --- /dev/null +++ b/source/scripts/dunarcherquestscript.psc @@ -0,0 +1,44 @@ +ScriptName dunArcherQuestScript extends Quest Conditional + +;Variable to track when player is in shooting box +Int Property playerInBox auto conditional + +;Variable to drive the angiFeeback scene +Int Property feedbackFlag auto conditional +{0=no problems, 1=player not in box, 2=player use wrong arrow, 3=player not in box and wrong arrow, 4=wrong target} + +;Variable to track if player has completed first challenge +Int Property playerChallengeComplete01 auto conditional + +;Variable to track if player is using the correct ammo type +Int Property playerUsingPracticeArrow auto conditional + +;Variable to track if player has hit the middle target +Int Property playerHitTargetMiddle auto conditional + +;Variable to track if player has hit the left target +Int Property playerHitTargetLeft auto conditional + +;Variable to track if player has hit the right target +Int Property playerHitTargetRight auto conditional + +;Variable to track if player has hit the far target +Int Property playerHitTargetFar auto conditional + +;Practice Arrows +Ammo property myAmmo auto + +Scene property angiShootsFirstTime auto +Scene property angiShootsSecondTime auto +Scene property angiShootsThirdTime auto +Scene property angiShootsFinalTime auto +Scene property playerHitMidTarget auto +Scene property playerShootsThreeTargets auto +Scene property playerShootsFarTarget auto +Scene property playerShootsAllTargets auto + +Weapon property angisBow auto +Int property FamilyStory auto conditional +Int property PlayerTookBow auto conditional + +Int property count = 0 auto hidden diff --git a/source/scripts/duncgfiretriggerscript.psc b/source/scripts/duncgfiretriggerscript.psc new file mode 100644 index 00000000..2576c234 --- /dev/null +++ b/source/scripts/duncgfiretriggerscript.psc @@ -0,0 +1,16 @@ +scriptName dunCGFireTriggerScript extends objectReference +{Actor enters trigger, he gets hurt} + + +keyword property dunCGMagicHeavyFire auto +explosion property dunCGTrapFireTriggerExplosion01 auto + +event onTrigger(objectReference triggerRef) + if triggerRef as actor && !(triggerRef as actor).isDead() + + ;If the actor does not already have this fire effect on them + if !(triggerRef as actor).HasMagicEffectWithKeyword(dunCGMagicHeavyFire) + triggerRef.placeAtMe(dunCGTrapFireTriggerExplosion01) + endif + endif +endEvent diff --git a/source/scripts/dunkagrenzelanimationresetscript.psc b/source/scripts/dunkagrenzelanimationresetscript.psc new file mode 100644 index 00000000..01ccf12c --- /dev/null +++ b/source/scripts/dunkagrenzelanimationresetscript.psc @@ -0,0 +1,19 @@ +scriptName dunKagrenzelAnimationResetScript extends ObjectReference + + +import debug +import utility + +objectReference property animObject auto +{reference the plays the animations} + +;************************************ + +Event onTriggerEnter(objectReference triggerRef) + Actor actorRef = triggerRef as Actor + if(actorRef == game.getPlayer()) + animObject.playAnimation("Reset") + endif +endEvent + +;************************************ \ No newline at end of file diff --git a/source/scripts/dunkarthspirepuzzlemaster.psc b/source/scripts/dunkarthspirepuzzlemaster.psc new file mode 100644 index 00000000..1c6eba7f --- /dev/null +++ b/source/scripts/dunkarthspirepuzzlemaster.psc @@ -0,0 +1,115 @@ +Scriptname dunKarthspirePuzzleMaster extends ObjectReference Conditional +{The master control script for the ring puzzle, it will keep all of the ring variables} + +; ********************************** +; ** THE STUFF FOR THE PILLAR PUZZLE +; ********************************** +INT PROPERTY pillarAState AUTO HIDDEN Conditional +INT PROPERTY pillarBState AUTO HIDDEN Conditional +INT PROPERTY pillarCState AUTO HIDDEN Conditional + +BOOL PROPERTY pillarSolved=FALSE AUTO HIDDEN Conditional + +OBJECTREFERENCE PROPERTY flameA AUTO +{PP: the flame for showing the way} +OBJECTREFERENCE PROPERTY flameB AUTO +{PP: the flame for showing the way} +OBJECTREFERENCE PROPERTY flameC AUTO +{PP: the flame for showing the way} +OBJECTREFERENCE PROPERTY flameD AUTO +{PP: the flame for showing the way} + +; ********************************* +; ** THE STUFF FOR THE PLATE PUZZLE +; ********************************* +BOOL PROPERTY plateTriggered=FALSE AUTO HIDDEN Conditional ; set to true when the player triggers a plate + +BOOL PROPERTY plateSolved=FALSE AUTO HIDDEN Conditional + +; ********************************* +; ** THE STUFF FOR THE RING PUZZLE +; ********************************* +INT PROPERTY ring1State AUTO HIDDEN +INT PROPERTY ring2State AUTO HIDDEN +INT PROPERTY ring3State AUTO HIDDEN +INT PROPERTY ring4State AUTO HIDDEN + +BOOL PROPERTY questDone=FALSE AUTO HIDDEN + +OBJECTREFERENCE PROPERTY puzzRing1 AUTO +OBJECTREFERENCE PROPERTY puzzRing2 AUTO +OBJECTREFERENCE PROPERTY puzzRing3 AUTO +OBJECTREFERENCE PROPERTY puzzRing4 AUTO + +; //FUNCTION: ringShift +; //int ring: an int representing the ring to spin +; // +; //PURPOSE: A cleaner way to spin the rings, plus it +; //lets us manipulate one function instead of 3 seperate +; //ones. + +FUNCTION ringShift(int ring) + + IF(ring == 1) + IF(ring1State == 1) + puzzRing1.playAnimation("Ring01Rotate01") + ring1State = 2 + ELSEIF(ring1State == 2) + puzzRing1.playAnimation("Ring01Rotate02") + ring1State = 3 + ELSEIF(ring1State == 3) + puzzRing1.playAnimation("Ring01Rotate03") + ring1State = 4 + ELSEIF(ring1State == 4) + puzzRing1.playAnimation("Ring01Rotate04") + ring1State = 1 + ENDIF + + ELSEIF(ring == 2) + IF(ring2State == 1) + puzzRing2.playAnimation("Ring01Rotate01") + ring2State = 2 + ELSEIF(ring2State == 2) + puzzRing2.playAnimation("Ring01Rotate02") + ring2State = 3 + ELSEIF(ring2State == 3) + puzzRing2.playAnimation("Ring01Rotate03") + ring2State = 4 + ELSEIF(ring2State == 4) + puzzRing2.playAnimation("Ring01Rotate04") + ring2State = 1 + ENDIF + + ELSEIF(ring == 3) + IF(ring3State == 1) + puzzRing3.playAnimation("Ring01Rotate01") + ring3State = 2 + ELSEIF(ring3State == 2) + puzzRing3.playAnimation("Ring01Rotate02") + ring3State = 3 + ELSEIF(ring3State == 3) + puzzRing3.playAnimation("Ring01Rotate03") + ring3State = 4 + ELSEIF(ring3State == 4) + puzzRing3.playAnimation("Ring01Rotate04") + ring3State = 1 + ENDIF + + ELSEIF(ring == 4) + IF(ring4State == 1) + puzzRing3.playAnimation("Ring01Rotate01") + ring4State = 2 + ELSEIF(ring4State == 2) + puzzRing4.playAnimation("Ring01Rotate02") + ring4State = 3 + ELSEIF(ring4State == 3) + puzzRing4.playAnimation("Ring01Rotate03") + ring4State = 4 + ELSEIF(ring4State == 4) + puzzRing4.playAnimation("Ring01Rotate04") + ring4State = 1 + ENDIF + + ENDIF + +ENDFUNCTION diff --git a/source/scripts/dunkatariahscimitarscript.psc b/source/scripts/dunkatariahscimitarscript.psc new file mode 100644 index 00000000..d4cf65ba --- /dev/null +++ b/source/scripts/dunkatariahscimitarscript.psc @@ -0,0 +1,7 @@ +Scriptname dunKatariahScimitarScript extends ActiveMagicEffect + +Event OnEffectStart(actor Target, actor Caster) + Game.GetPlayer().PushActorAway(Target, PushForce) +EndEvent + +int Property PushForce Auto diff --git a/source/scripts/dunmiddentorchscript.psc b/source/scripts/dunmiddentorchscript.psc new file mode 100644 index 00000000..4daf357a --- /dev/null +++ b/source/scripts/dunmiddentorchscript.psc @@ -0,0 +1,58 @@ +scriptName dunMiddenTorchSCRIPT extends objectReference +{Configurable Custom Script. Be default: when triggered, it will cast the spell from a linked ref at the triggering actor} + +float property delayBetween auto +{seconds to wait between shots. Only relevant if doOnce == false} +;light property myLight auto +;{light to cast} +;projectile property myFX auto +;{light FX object to place} + +auto STATE active + EVENT onTriggerEnter(ObjectReference actronaut) + if actronaut == game.getPlayer() + ;gotoState("inactive") + getLinkedRef().enable(true) + ;utility.wait(delayBetween) + ;gotostate("active") + endif + endEVENT + + EVENT onTriggerLeave(objectReference actronaut) + if actronaut == game.getPlayer() + getLinkedRef().disable(true) + endif + endEVENT +endSTATE + +STATE inactive + ; nothing happens here. +endSTATE + + ; objectReference myFXref + ; myFXref = getLinkedRef().placeatme(myFX) + ; myFXref.setScale(0.1) + ;;send to inert state + ; gotoState ("inactive") + ; int i = 0 + ; while myFXref.getScale() < 1.0 + ;;store the current scale for later + ; float fScale = myFXref.getscale() +; ; debug.trace(self + "fScale = " + fscale) + ; i += 1 + ; if i > 1000 + ;;too many loops. Force full scale and kill the script +; ; debug.traceStack(self + "looped too many times, killing it. Scale was: " + fScale, 0) + ; myFXref.disable(true) + ; myFXref.delete() + ; gotoState("active") + ; return + ; endif + ; float newScale = (fScale + 0.01) + ; myFXref.setScale(newScale) + ; endwhile + ;;begin the delay wait after we've reached full scale + ; utility.wait(delayBetween) + ; gotoState("active") + ; endif + ; endEVENT \ No newline at end of file diff --git a/source/scripts/dwepipevalve01script.psc b/source/scripts/dwepipevalve01script.psc new file mode 100644 index 00000000..47c36323 --- /dev/null +++ b/source/scripts/dwepipevalve01script.psc @@ -0,0 +1,19 @@ +scriptName DwePipeValve01SCRIPT extends ObjectReference + +bool property bidirectional = False Auto +{Should the valve alternate directions with each activation? Default: False} + +bool flip = False + +Auto STATE Waiting + EVENT onActivate (objectReference triggerRef) + self.BlockActivation(true) + if (flip) + playAnimationandWait("trigger02","Trans02") + Else + playAnimationandWait("trigger01","Trans01") + EndIf + flip = !flip + self.BlockActivation(false) + endEVENT +endState \ No newline at end of file diff --git a/source/scripts/dwespherecenturionportscript.psc b/source/scripts/dwespherecenturionportscript.psc new file mode 100644 index 00000000..533dd09d --- /dev/null +++ b/source/scripts/dwespherecenturionportscript.psc @@ -0,0 +1,28 @@ +scriptName dweSphereCenturionPortScript extends ObjectReference + +import debug +import utility + +;**************************************** + +auto State Listening + + Event onActivate(objectReference triggerRef) + Actor myActor = triggerRef as Actor + if (myActor.getState() != "Waiting") + gotoState("done") + playAnimation("open") + wait(2) + playAnimation("close") + endif + endEvent + +endState + +;**************************************** + +State done + ;do nothing +endState + +;**************************************** \ No newline at end of file diff --git a/source/scripts/dwespidercenturionpipescript.psc b/source/scripts/dwespidercenturionpipescript.psc new file mode 100644 index 00000000..8c338e5a --- /dev/null +++ b/source/scripts/dwespidercenturionpipescript.psc @@ -0,0 +1,26 @@ +scriptName dweSpiderCenturionPipeScript extends ObjectReference + +import debug +import utility + +;**************************************** + +auto State Listening + + Event onActivate(objectReference triggerRef) + Actor myActor = triggerRef as Actor + if (myActor.getState() != "Waiting") + gotoState("done") + playAnimation("exit") + endif + endEvent + +endState + +;**************************************** + +State done + ;do nothing +endState + +;**************************************** \ No newline at end of file diff --git a/source/scripts/dwesteamcenturionstructurescript.psc b/source/scripts/dwesteamcenturionstructurescript.psc new file mode 100644 index 00000000..78a5d4b6 --- /dev/null +++ b/source/scripts/dwesteamcenturionstructurescript.psc @@ -0,0 +1,28 @@ +scriptName dweSteamCenturionStructureScript extends ObjectReference + +import debug +import utility + +;**************************************** + +auto State Listening + + Event onActivate(objectReference triggerRef) + Actor myActor = triggerRef as Actor + if (myActor.getState() != "Waiting") + gotoState("done") + playAnimation("Trigger01") + ;wait(2) + ;playAnimation("close") + endif + endEvent + +endState + +;**************************************** + +State done + ;do nothing +endState + +;**************************************** \ No newline at end of file diff --git a/source/scripts/favordialoguescript.psc b/source/scripts/favordialoguescript.psc new file mode 100644 index 00000000..66bd99fd --- /dev/null +++ b/source/scripts/favordialoguescript.psc @@ -0,0 +1,152 @@ +Scriptname FavorDialogueScript extends Quest Conditional +{functions and properties used by favor dialogue} + +GlobalVariable Property GameDaysPassed Auto + +GlobalVariable Property IntimidateBribeDelayDays Auto + +GlobalVariable Property FlatterDelayDays Auto + +GlobalVariable Property BribeReward Auto + +GlobalVariable Property FlatterReward Auto + +GlobalVariable Property IntimidateReward Auto + +GlobalVariable Property IntimidateCost Auto +{favor point cost from intimidating} + +MiscObject Property Gold Auto + +Keyword Property BrawlKeyword Auto +{used for brawl story event} + +CompanionsRadiantQuest Property CR04 Auto +{One of the Companions quests cares about intimidating someone specific} + +ReferenceAlias Property MS10Stig Auto +{MS10 needs to be told after intimidating Stig} + +float Property SkillUsePersuade Auto Conditional +{skill uses for flatter (magnitude for AdvanceSkill)} + +float Property SkillUseBribe Auto Conditional +{skill uses for flatter (magnitude for AdvanceSkill)} + +float Property SkillUseIntimidate Auto Conditional +{skill uses for flatter (magnitude for AdvanceSkill)} + +float Property SkillUseMultiplier Auto Conditional +{Base multiplier for skill uses. Formula is based off the skill use multiplier set in Speechcraftt} + +float Property SkillUseGiveGiftMult = 1.0 Auto Conditional +{skill uses for flatter (multipler for for AdvanceSkill magnitude)} + +GlobalVariable Property SpeechSkillMult Auto +{Global to determine skill uses} + +import game +import debug + +; call this to persuade target actor + +Function Persuade(Actor pTarget) + trace("Persuade: " + pTarget) + ; give player skill uses + SkillUseMultiplier = SpeechSkillMult.value + SkillUsePersuade = SkillUseMultiplier * Game.GetPlayer().GetAv("Speechcraft") + trace(self + "Current Skill uses given: " + SkillUsePersuade + " times the Skill Use Multiplier") + AdvanceSkill("Speechcraft", SkillUsePersuade) + Game.IncrementStat( "Persuasions" ) + if ( Game.QueryStat( "Bribes" ) && Game.QueryStat( "Intimidations" ) ) + AddAchievement(28) + endif +endFunction + +Function ArrestPersuade(Actor pTarget) + trace("Persuade: " + pTarget) + ; give player skill uses + SkillUseMultiplier = SpeechSkillMult.value + SkillUsePersuade = SkillUseMultiplier * Game.GetPlayer().GetAv("Speechcraft") + AdvanceSkill("Speechcraft", SkillUsePersuade) + Game.IncrementStat( "Persuasions" ) + if ( Game.QueryStat( "Bribes" ) && Game.QueryStat( "Intimidations" ) ) + AddAchievement(28) + endif + ; set bribed state + pTarget.SetBribed() +endFunction + + +; call this to bribe target actor +Function Bribe(Actor pTarget) + trace("Bribe: " + pTarget) + SkillUseMultiplier = SpeechSkillMult.value + SkillUseBribe = SkillUseMultiplier * Game.GetPlayer().GetAv("Speechcraft") + trace(self + "Current Skill uses given: " + SkillUseBribe + " times the Skill Use Multiplier") + if pTarget.GetBribeAmount() <= GetPlayer().GetGoldAmount() + ; remove gold + GetPlayer().RemoveItem(Gold, pTarget.GetBribeAmount()) + ; put gold in target + pTarget.AddItem(Gold, pTarget.GetBribeAmount()) + ; set bribed state + pTarget.SetBribed() + ; give player skill uses + AdvanceSkill("Speechcraft", SkillUseBribe) + ; increment game stats + Game.IncrementStat( "Bribes" ) + if ( Game.QueryStat( "Persuasions" ) && Game.QueryStat( "Intimidations" ) ) + Game.AddAchievement(28) + endif + endif +endFunction + +; call this to intimidate target actor +Function Intimidate(Actor pTarget) + trace("Intimidate: " + pTarget) + SkillUseMultiplier = SpeechSkillMult.value + SkillUseIntimidate = SkillUseMultiplier * Game.GetPlayer().GetAv("Speechcraft") + trace(self + "Current Skill uses given: " + SkillUseIntimidate + " times the Skill Use Multiplier") + ; intimidate actor + pTarget.SetIntimidated() + ; give player skill uses. don't if the Brawl quest is running, don't track intimidation stats for Brawl + If DGintimidateQuest.IsRunning() == False + AdvanceSkill("Speechcraft", SkillUseIntimidate) + Game.IncrementStat( "Intimidations" ) + if ( Game.QueryStat( "Persuasions" ) && Game.QueryStat( "Bribes" ) ) + Game.AddAchievement(28) + endif + EndIf + + if ( CR04.IsRunning() && (10 == CR04.GetStage()) ) + (CR04 as CR04QuestScript).CheckIntimidate(pTarget) + endif + if (pTarget == MS10Stig.GetActorReference()) + (MS10Stig.GetOwningQuest() as MS10QuestScript).GetErDoneWithStig() + endif +endFunction + +; call this to initiate brawl quest through story manager +Function Brawl(Actor pTarget, Actor pTargetFriend = None) + trace("Brawl: " + pTarget + ", friend=" + pTargetFriend) + BrawlKeyword.SendStoryEvent(None, pTarget, pTargetFriend) +endFunction + +; call this to give gift to target actor +Function GiveGift(Actor pTarget) + FormList giftFilter = pTarget.GetActorBase().GetGiftFilter() + trace("Give Gift: " + pTarget + ", gift filter = " + giftFilter) + int favorPointsEarned = pTarget.ShowGiftMenu(true, giftFilter) + ; TEMP cap until we have a formula for this: + if favorPointsEarned > 100 + favorPointsEarned = 100 + endif + ; give player skill uses + trace("Give Gift: " + favorPointsEarned * SkillUseGiveGiftMult + " skill uses earned") + AdvanceSkill("Speechcraft", favorPointsEarned * SkillUseGiveGiftMult) +endFunction + + +Quest Property DGIntimidateQuest Auto + + diff --git a/source/scripts/flameatronacheffectscript.psc b/source/scripts/flameatronacheffectscript.psc new file mode 100644 index 00000000..f3d24963 --- /dev/null +++ b/source/scripts/flameatronacheffectscript.psc @@ -0,0 +1,48 @@ +Scriptname FlameAtronachEffectScript extends ActiveMagicEffect + +{This is a temp script to get the art working right for the flame atronach.} +;=============================================== + +import utility +import form + +;=============================================== + +Actor selfRef +VisualEffect Property AtronachFlameTrail Auto +Armor Property AtronachFlameDeadSkin Auto +EffectShader Property AtronachFlameDeathFXS Auto +EffectShader Property AtronachUnsummonDeathFXS Auto +explosion property AtronachFlameDeathExplosion auto +int atronachHealth + + EVENT OnEffectStart(Actor Target, Actor Caster) + selfRef = caster + AtronachFlameTrail.Play(selfRef, -1) + ENDEVENT + + Event OnEffectFinish(Actor akTarget, Actor akCaster) + AtronachFlameTrail.Stop(selfRef) + ENDEVENT + + EVENT onDying(actor myKiller) + atronachHealth = selfRef.GetAV("Health") as int + if atronachHealth > 0 +; debug.trace("flame health > 0") + AtronachFlameTrail.Stop(selfRef) + AtronachUnsummonDeathFXS.Play(selfRef) + elseIf atronachHealth <= 0 + wait(3.0) +; debug.trace("flame health <= 0") + AtronachFlameDeathFXS.Play(selfRef) + wait(0.5) + selfRef.placeAtMe(AtronachFlameDeathExplosion) + wait(0.1) + AtronachFlameTrail.Stop(selfRef) + selfRef.EquipItem(AtronachFlameDeadSkin) + wait(1) + AtronachFlameDeathFXS.Stop(selfRef) + endif + ENDEVENT + + diff --git a/source/scripts/fxbatscaredscript.psc b/source/scripts/fxbatscaredscript.psc new file mode 100644 index 00000000..15be3f95 --- /dev/null +++ b/source/scripts/fxbatscaredscript.psc @@ -0,0 +1,43 @@ +Scriptname FXbatScaredSCRIPT extends ObjectReference +{Runs the bats animations when trigger box is entered.} + + +;=============================================== + +import debug ; import debug.psc for acces to trace() +import utility ; utility.psc for access to wait() + +sound property mySFX auto ; specify sound fx to play +weapon property weapLg auto ; specify large weapon type +ammo property myAmmo auto ; specify ammo type + +float rndWaitTimer + +;=============================================== + + +auto STATE waiting + Event onTriggerEnter(ObjectReference akActionRef) + if (akActionRef == game.getPlayer() as ObjectReference) + ;go to an empty state while we take care of the FX + gotoState("busy") + + ;take care of FX + mySFX.play(self) + weapLg.fire(self, myAmmo) + playAnimationAndWait("MothTakeoff", "End") + + ;now wait + wait(RandomInt(20,30)) + + ;done waiting, now get out of the "busy" state and back to "waiting" state + goToState ("waiting") + endif + endEvent +endState + +;=============================================== + +State busy + ;do nothing +EndState diff --git a/source/scripts/fxbirdfleescript.psc b/source/scripts/fxbirdfleescript.psc new file mode 100644 index 00000000..8921ec91 --- /dev/null +++ b/source/scripts/fxbirdfleescript.psc @@ -0,0 +1,44 @@ +Scriptname FXBirdFleeSCRIPT extends ObjectReference +{Triggers birds to fly away} + +import debug ; import debug.psc for acces to trace() +import game ; game.psc for access to getPlayer() +import utility ; utility.psc for access to wait() +import sound ; sound.psc for access to play() + +sound property BirdFlockSound auto +sound property BirdFlockFleeSound auto +bool property PlayerTriggered = false auto +{check if player is only actor that can trigger - Default FALSE} + +int instanceID00 + +;************************************************* + +Event onCellAttach() + instanceID00 = BirdFlockSound.Play(Self) + gotoState("Waiting") +endEvent + +;************************************************* + +State Waiting + Event onTriggerEnter(ObjectReference akActionRef) + Actor actionRef = akActionRef as Actor + if(((PlayerTriggered) && (actionRef == game.GetPlayer() as Actor)) || (PlayerTriggered == False)) + gotoState("doNothing") + Self.PlayAnimation("PlayAnim01") + int instanceID01 = BirdFlockFleeSound.Play(Self) + wait (0.5) + StopInstance(instanceID00) + endif + endEvent +endState + +;************************************************* + +State doNothing + ;do nothing +endState + +;************************************************* \ No newline at end of file diff --git a/source/scripts/fxchaurusscript.psc b/source/scripts/fxchaurusscript.psc new file mode 100644 index 00000000..aa655531 --- /dev/null +++ b/source/scripts/fxchaurusscript.psc @@ -0,0 +1,32 @@ +Scriptname FXChaurusScript extends ActiveMagicEffect +{This script managage the fx art for the Charus} +;=============================================== + +;=============================================== + +Actor selfRef +Armor Property ChaurusSpitSkin Auto + + + EVENT OnEffectStart(Actor Target, Actor Caster) + selfRef = caster + if (selfRef.GetSleepState() == 3) +; Debug.Trace("Charus is sleeping! 3") + else + selfRef.EquipItem(ChaurusSpitSkin) + endIf + ENDEVENT + + Event OnEffectFinish(Actor akTarget, Actor akCaster) + selfRef.UnequipItem(ChaurusSpitSkin) + endEvent + + Event OnGetUp(ObjectReference akFurniture) +; Debug.Trace("Charus just got up from " ) + selfRef.EquipItem(ChaurusSpitSkin) + endEvent + + EVENT onDeath(actor myKiller) + selfRef.UnequipItem(ChaurusSpitSkin) + ENDEVENT + diff --git a/source/scripts/fxdragonblooddamagescript.psc b/source/scripts/fxdragonblooddamagescript.psc new file mode 100644 index 00000000..08209b8b --- /dev/null +++ b/source/scripts/fxdragonblooddamagescript.psc @@ -0,0 +1,360 @@ +Scriptname FXDragonBloodDamageScript extends ActiveMagicEffect +{This script applies blood damage geometry to the dragon and turns it on when they are hit based on the direction they are hit from} + +;=============================================== +; MARK'S ORIGINAL VARS & PROPERTIES +int frontBloodStepper +int backBloodStepper +int leftBloodStepper +int rightBloodStepper +int dragonHealth +string hitDirection ;0=front 1=right 2=back 3=left +float hitAngle +Armor Property DragonBloodHeadFXArmor Auto +Armor Property DragonBloodTailFXArmor Auto +Armor Property DragonBloodWingLFXArmor Auto +Armor Property DragonBloodWingRFXArmor Auto +Actor selfRef + +; JOEL'S VARS & PROPERTIES +; user can override HP percentages +float property HPpctT1 = 0.98 auto +{relative total HP at which first blood should appear DEFAULT: 0.??} +float property HPpctT2 = 0.95 auto +{relative total HP at which second blood should appear DEFAULT: 0.??} +float property HPpctT3 = 0.90auto +{relative total HP at which third blood should appear DEFAULT: 0.??} +float property HPpctT4 = 0.80 auto +{relative total HP at which final blood should appear DEFAULT: "+HPpctT4} + +float previousHP +float diffHP + +; tracking values for the amount of damage each "side" has taken. +float HPFront +float HPBack +float HPLeft +float HPRight + +; tracking vars for damage to each side +; 0 = no blood, 1 = tier 1 blood, etc. +int stateFront = 0 +int stateBack = 0 +int stateLeft = 0 +int stateRight = 0 + +; HP tiers. These are the threshold values below which each blood will play +float HPt1 +float HPt2 +float HPt3 +float HPt4 + +bool bDebug = FALSE + +;=============================================== + + +EVENT OnEffectStart(Actor Target, Actor Caster) + ;Setup stuff has to go here for activeMagicEffect + selfRef = caster + ; store HP for future use. THis should usually be 100% HP. + previousHP = selfRef.getActorValue("health") +; ; debug.TraceConditional("TEST JOEL: Dragon has set previousHP to :"+previousHP, bDebug) +; ; debug.TraceConditional("TEST JOEL: Dragon Blood FX onEffectStart initialized", bDebug) + dragonBloodInit() +ENDEVENT + +EVENT onLoad() +; ; debug.traceConditional("TEST JOEL: Dragon has loaded ("+selfRef+")", bDebug) +endEVENT + +EVENT OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + + ; first intercept to figure out how much damage was done. +; ; debug.TraceConditional("||===============================", bDebug) +; ; debug.TraceConditional("|| TEST JOEL: DRAGON HP DIAGNOSTIC", bDebug) +; ; debug.TraceConditional("|| TEST JOEL: Dragon previous HP="+previousHP, bDebug) +; ; debug.TraceConditional("|| TEST JOEL: Dragon current HP="+selfRef.getActorValue("health"), bDebug) + + diffHP = previousHP - (selfRef.getActorValue("health")) +; ; debug.TraceConditional("|| TEST JOEL: Dragon damaged for "+diffHP+"HP", bDebug) + + ; determine if I was hit in the front/back/left/right + hitAngle = selfRef.GetHeadingAngle(akAggressor) + if hitAngle >= -45 && hitAngle <= 45 + hitDirection = "FRONT" + ; decrement a fake HP counter for this side of the body + HPfront = (HPfront - diffHP) + endif + if hitAngle >= 135 || hitAngle <= -135 + hitDirection = "BACK" + ; decrement a fake HP counter for this side of the body + HPback = (HPback - diffHP) + endif + if hitAngle < -45 && hitAngle > -135 + hitDirection = "LEFT" + ; decrement a fake HP counter for this side of the body + HPleft = (HPleft - diffHP) + endif + if hitAngle > 45 && hitAngle < 135 + hitDirection = "RIGHT" + ; decrement a fake HP counter for this side of the body + HPright = (HPright - diffHP) + endif + +; ; debug.TraceConditional("|| TEST JOEL: Dragon was hit from the "+hitDirection, bDebug) +; ; debug.TraceConditional("|| TEST JOEL: "+hitdirection+" HP = "+HPleft, bDebug) + + ; ============================================== + ; check for updates to blood state + if hitDirection == "FRONT" + + int prevStateFront = stateFront + + if (HPfront <= HPt1) && (HPfront > HPt2) + stateFront = 1 + elseif (HPfront <= HPt2) && (HPfront > HPt3) + stateFront = 2 + elseif (HPfront <= HPt3) && (HPfront > HPt4) + stateFront = 3 + elseif (HPfront <= HPt4) + stateFront = 4 + endif + + ; see if there was a change in state for this side + if stateFront != prevStateFront + ; concatenate and play appropriate blood FX +; ; debug.TraceConditional("|| TEST JOEL: Blood FX State Change: HeadBleed0"+stateFront, bDebug) + selfRef.PlaySubGraphAnimation("HeadBleed0"+stateFront) + endif + endif + + if hitDirection == "BACK" + + int prevStateback = stateback + + if (HPback <= HPt1) && (HPback > HPt2) + stateback = 1 + elseif (HPback <= HPt2) && (HPback > HPt3) + stateback = 2 + elseif (HPback <= HPt3) && (HPback > HPt4) + stateback = 3 + elseif (HPback <= HPt4) + stateback = 4 + endif + + ; see if there was a change in state for this side + if stateback != prevStateback + ; concatenate and play appropriate blood FX +; ; debug.TraceConditional("|| TEST JOEL: Blood FX State Change: BackBleed0"+stateback, bDebug) + selfRef.PlaySubGraphAnimation("TailBleed0"+stateback) + endif + endif + + if hitDirection == "LEFT" + + int prevStateleft = stateleft + + if (HPleft <= HPt1) && (HPleft > HPt2) + stateleft = 1 + elseif (HPleft <= HPt2) && (HPleft > HPt3) + stateleft = 2 + elseif (HPleft <= HPt3) && (HPleft > HPt4) + stateleft = 3 + elseif (HPleft <= HPt4) + stateleft = 4 + endif + + ; see if there was a change in state for this side + if stateleft != prevStateleft + ; concatenate and play appropriate blood FX +; ; debug.TraceConditional("|| TEST JOEL: Blood FX State Change: WingLBleed0"+stateleft, bDebug) + selfRef.PlaySubGraphAnimation("WingLBleed0"+stateleft) + endif + endif + + if hitDirection == "RIGHT" + + int prevStateright = stateright + + if (HPright <= HPt1) && (HPright > HPt2) + stateright = 1 + elseif (HPright <= HPt2) && (HPright > HPt3) + stateright = 2 + elseif (HPright <= HPt3) && (HPright > HPt4) + stateright = 3 + elseif (HPright <= HPt4) + stateright = 4 + endif + + ; see if there was a change in state for this side + if stateright != prevStateright + ; concatenate and play appropriate blood FX +; ; debug.TraceConditional("|| TEST JOEL: Blood FX State Change: WingRBleed0"+stateright, bDebug) + selfRef.PlaySubGraphAnimation("WingRBleed0"+stateright) + endif + endif + + ; ============================================== + ; store our current HP as the previous for accurate maths on future hits. + previousHP = selfRef.getActorValue("health") + if bDebug == TRUE +; ; debug.TraceConditional("|| TEST JOEL: End of onHit()", bDebug) + bDebug = false + debugVars() + endif + +endEVENT + +; EVENT onDeath(actor myKiller) + ; utility.wait(8.5) + ; selfRef.PlaySubGraphAnimation("BloodFade") + ; utility.wait(1.5) +; ENDEVENT + + +;==================================================================== +; Initialize a bunch of variables +;==================================================================== +FUNCTION dragonBloodInit() + ; quick safety net to convert percentages if they are entered incorrectly (ie 75% = 0.75) +; ; debug.TraceConditional("convert % values to integers", bDebug) + if HPpctT1 > 1.0 && HPpctT1 < 100 + HPpctT1 = HPpctT1*0.01 + endif + if HPpctT2 > 1.0 && HPpctT2 < 100 + HPpctT2 = HPpctT2*0.01 + endif + if HPpctT2 > 1.0 && HPpctT2 < 100 + HPpctT2 = HPpctT2*0.01 + endif + if HPpctT3 > 1.0 && HPpctT3 < 100 + HPpctT3 = HPpctT3*0.01 + endif + + ; store hard point values so we don't have to always work in percentages later + HPt1 = HPpctT1 * (selfRef.getBaseAV("health")) + HPt2 = HPpctT2 * (selfRef.getBaseAV("health")) + HPt3 = HPpctT3 * (selfRef.getBaseAV("health")) + HPt4 = HPpctT4 * (selfRef.getBaseAV("health")) + + ; set fake location HP counters to current(assume full?) HP + HPfront = selfRef.getAV("health") + HPback = selfRef.getAV("health") + HPleft = selfRef.getAV("health") + HPright = selfRef.getAV("health") + + if bDebug == TRUE +; ; debug.TraceConditional("|| TEST JOEL : finished Init()", bDebug) + debugVars() + endif + +endFUNCTION + +FUNCTION debugVars() +; ; debug.TraceConditional("||===============================", bDebug) +; ; debug.TraceConditional("|| DRAGON BLOOD FX VARIABLE READOUT", bDebug) +; ; debug.TraceConditional("|| HPpctT1 = "+HPpctT1, bDebug) +; ; debug.TraceConditional("|| HPpctT2 = "+HPpctT2, bDebug) +; ; debug.TraceConditional("|| HPpctT3 = "+HPpctT3, bDebug) +; ; debug.TraceConditional("|| HPpctT4 = "+HPpctT4, bDebug) +; ; debug.TraceConditional("|| HPFront = "+HPFront, bDebug) +; ; debug.TraceConditional("|| HPBack = "+HPBack, bDebug) +; ; debug.TraceConditional("|| HPLeft = "+HPLeft, bDebug) +; ; debug.TraceConditional("|| HPRight = "+HPRight, bDebug) +; ; debug.TraceConditional("|| stateFront = "+stateFront, bDebug) +; ; debug.TraceConditional("|| stateBack = "+stateBack, bDebug) +; ; debug.TraceConditional("|| stateLeft = "+stateLeft, bDebug) +; ; debug.TraceConditional("|| stateRight = "+stateRight, bDebug) +; ; debug.TraceConditional("|| HPt1 = "+HPt1, bDebug) +; ; debug.TraceConditional("|| HPt2 = "+HPt2, bDebug) +; ; debug.TraceConditional("|| HPt3 = "+HPt3, bDebug) +; ; debug.TraceConditional("|| HPt4 = "+HPt4, bDebug) +endFUNCTION + + + + + + + + + + + + +STATE markSTATE + + Event OnLoad() +; ;Debug.Trace("This dragon is loaded, playing animations should work now") + + + endEvent + + EVENT OnEffectStart(Actor Target, Actor Caster) + ;Play your particles. + selfRef = caster + dragonHealth = selfRef.GetAV("Health") as int + ENDEVENT + + + Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + + dragonHealth = selfRef.GetAV("Health") as int +; ; Debug.TraceConditional("Dragon's health is" + dragonHealth, bDebug) + hitAngle = selfRef.GetHeadingAngle(akAggressor) + if hitAngle >= -45 && hitAngle <= 45 +; ; Debug.TraceConditional(akAggressor + " angle is " + hitAngle, bDebug) +; ; Debug.TraceConditional("Dragon was hit in front", bDebug) + hitDirection = 0 + frontBloodStepper = frontBloodStepper + 1 + elseIf hitAngle > 45 && hitAngle < 135 +; ; Debug.TraceConditional(akAggressor + " angle is " + hitAngle, bDebug) +; ; Debug.TraceConditional("Dragon was hit on right", bDebug) + hitDirection = 1 + rightBloodStepper = rightBloodStepper + 1 + elseIf hitAngle >= 135 || hitAngle <= -135 +; ; Debug.TraceConditional(akAggressor + " angle is " + hitAngle, bDebug) +; ; Debug.TraceConditional("Dragon was hit in back", bDebug) + hitDirection = 2 + backBloodStepper = backBloodStepper + 1 + elseIf hitAngle < -45 && hitAngle > -135 +; ; Debug.TraceConditional(akAggressor + " angle is " + hitAngle, bDebug) +; ; Debug.TraceConditional("Dragon was hit on left", bDebug) + hitDirection = 3 + leftBloodStepper = leftBloodStepper + 1 + endif + + if hitDirection == 0 + if frontBloodStepper <= 4 +; ; Debug.TraceConditional("Dragon head blood stage0" + frontBloodStepper, bDebug) + selfRef.PlaySubGraphAnimation("HeadBleed0" + frontBloodStepper) + endif + elseif hitDirection == 1 + if rightBloodStepper <= 4 +; ; Debug.TraceConditional("Dragon wing r blood stage0" + rightBloodStepper, bDebug) + selfRef.PlaySubGraphAnimation("WingRBleed0" + rightBloodStepper) + endif + elseif hitDirection == 2 + if backBloodStepper <= 4 +; ; Debug.TraceConditional("Dragon back blood stage0" + backBloodStepper, bDebug) + selfRef.PlaySubGraphAnimation("TailBleed0" + backBloodStepper) + endif + elseif hitDirection == 3 + if leftBloodStepper <= 4 +; ; Debug.TraceConditional("Dragon wing l blood stage0" + leftBloodStepper, bDebug) + selfRef.PlaySubGraphAnimation("WingLBleed0" + leftBloodStepper) + endif + endif + + + ENDEVENT + + + EVENT onDeath(actor myKiller) + + ; selfRef.UnequipItem(ChaurusSpitSkin) + + ENDEVENT +endSTATE + diff --git a/source/scripts/fxdraugrmagicscript.psc b/source/scripts/fxdraugrmagicscript.psc new file mode 100644 index 00000000..93b59b67 --- /dev/null +++ b/source/scripts/fxdraugrmagicscript.psc @@ -0,0 +1,81 @@ +Scriptname FxDraugrMagicScript extends ActiveMagicEffect +{Add magic draugr fx} + + + +import utility +import form + +;=============================================== + +ObjectReference selfRef +ActorBase myActorBase +int draugrSex +VisualEffect Property DraugrMaleEyeGlowFX Auto +VisualEffect Property DraugrFemaleEyeGlowFX Auto +VisualEffect Property FXMagicDraugrDarkeningEffect Auto +; VisualEffect Property FXDraugrMagicSwordStreakEffect Auto +; VisualEffect Property FXDraugrMagicAxeStreakEffect Auto +; VisualEffect Property FXDraugrMagicBowStreakEffect Auto +weapon property Sword1H auto +weapon property Axe2H auto +weapon property Bow auto + + + EVENT OnEffectStart(Actor Target, Actor Caster) + selfRef = caster + myActorBase = caster.GetLeveledActorBase() + ;add darkened area fx to all magic draugr + FXMagicDraugrDarkeningEffect.Play(selfRef, -1) + ;If sex is male (only one currently working) play glow eye art + if myActorBase.GetSex() == 0 + ;Play glow art + DraugrMaleEyeGlowFX.Play(selfRef, -1) + endif + ;if sex is female (currently not returned) play debug text to say this is now working + if myActorBase.GetSex() == 1 + DraugrFemaleEyeGlowFX.Play(selfRef, -1) + endif + ; apply appropriate streak FX if I have a weapon + ; if selfRef.getItemCount(Sword1H) >= 1 + ; caster.equipItem(Sword1H, TRUE, TRUE) + ;FXDraugrMagicSwordStreakEffect.Play(selfRef, -1) + ; elseif selfRef.getItemCount(Axe2H) >= 1 + ; caster.equipItem(Axe2H, TRUE, TRUE) + ;FXDraugrMagicAxeStreakEffect.Play(selfRef, -1) + ; elseif selfRef.getItemCount(Bow) >= 1 + ; caster.equipItem(Bow, TRUE, TRUE) + ; FXDraugrMagicBowStreakEffect.Play(selfRef, -1) + ; endif + ENDEVENT + + Event OnEffectFinish(Actor akTarget, Actor akCaster) + FXMagicDraugrDarkeningEffect.Stop(selfRef) + if myActorBase.GetSex() == 0 + ;Play glow art + DraugrMaleEyeGlowFX.Stop(selfRef) + endif + if myActorBase.GetSex() == 1 + DraugrFemaleEyeGlowFX.Stop(selfRef) + endif + ; if selfRef.getItemCount(Sword1H) >= 1 + ; caster.equipItem(Sword1H, TRUE, TRUE) + ; FXDraugrMagicSwordStreakEffect.Stop(selfRef) + ; elseif selfRef.getItemCount(Axe2H) >= 1 + ; caster.equipItem(Axe2H, TRUE, TRUE) + ; FXDraugrMagicAxeStreakEffect.Stop(selfRef) + ; elseif selfRef.getItemCount(Bow) >= 1 + ; caster.equipItem(Bow, TRUE, TRUE) + ; FXDraugrMagicBowStreakEffect.Stop(selfRef) + ; endif + endEvent + + EVENT onDying(actor myKiller) + + ;DraugrMaleEyeGlowFX.Stop(selfRef) + ;DraugrFemaleEyeGlowFX.Stop(selfRef) + FXMagicDraugrDarkeningEffect.Stop(selfRef) + ; FXDraugrMagicSwordStreakEffect.Stop(selfRef) + + ENDEVENT + \ No newline at end of file diff --git a/source/scripts/fxdustdroponactivatescript.psc b/source/scripts/fxdustdroponactivatescript.psc new file mode 100644 index 00000000..ad4b66f3 --- /dev/null +++ b/source/scripts/fxdustdroponactivatescript.psc @@ -0,0 +1,42 @@ +scriptName FXdustDropOnActivateSCRIPT extends objectReference +{this Script plays three dust falling animations when triggered} +;=============================================== + +import debug ; import debug.psc for acces to trace() +import utility ; utility.psc for access to wait() +import sound ; sound.psc for access to play() + +;=============================================== +Explosion property FallingDustExplosion01 auto +sound property mySFX auto ; specify SFX to play + +;********************************* + +auto State waiting + Event onActivate(objectReference triggerRef) +; debug.trace(self + " activated") + ;;Actor actorRef = triggerRef as Actor + ;if(actorRef == game.getPlayer()) + ;player has entered trigger + gotoState("done") + self.PlayAnimation("PlayAnim01") + mySFX.play(self) + wait(0.3) + placeAtMe(FallingDustExplosion01) + wait(3.0) + self.PlayAnimation("PlayAnim02") + mySFX.play(self) + wait(3.3) + self.PlayAnimation("PlayAnim03") + mySFX.play(self) + ;endif + endEvent +endSTATE + +;********************************* + +State done + ;do nothing +endState + +;********************************* diff --git a/source/scripts/fxdustdroptrigscript.psc b/source/scripts/fxdustdroptrigscript.psc new file mode 100644 index 00000000..eedc8b9b --- /dev/null +++ b/source/scripts/fxdustdroptrigscript.psc @@ -0,0 +1,85 @@ +scriptName FXdustDropTrigSCRIPT extends objectReference +{this Script controls randomized dustfalls} +;=============================================== + +import debug ; import debug.psc for acces to trace() +import game ; game.psc for access to getPlayer() +import utility ; utility.psc for access to wait() +import sound ; sound.psc for access to play() + +;=============================================== +Explosion property FallingDustExplosion01 auto +sound property mySFX auto ; specify SFX to play +int chooser ; random FX choice integer +float rndWaitTimer ; we'll randomize how long we wait between FX +;=============================================== + +;function playFX(int chooser) +; if chooser == 1 + ; MARK - there's a playgroup forward in your script here but not in the others. Hur? +; self.PlayGamebryoAnimation("Forward") +; weapLg.fire(self, myAmmoMed) +; elseif chooser == 2 +; self.PlayGamebryoAnimation("Backward") +; weapMd.fire(self, myAmmoSm) +; elseif chooser == 3 +; self.PlayGamebryoAnimation("Left") +; weapSm.fire(self, myAmmoTiny) +; endif +; mySFX.play(self) ; same sound no matter what vizFX we choose. +; rndWaitTimer = RandomInt(1,5) +; wait(rndWaitTimer) ; sit around for 1-5 seconds +; gotoState("latent") +;endFunction + +;=============================================== + +auto STATE latent ; by default, just sit still and wait for a trigger event + EVENT onTriggerENTER(objectReference trigRef) + if trigRef == getPlayer() +; Debug.Trace("Triggered") + chooser = RandomInt(1,3) ; generate a random number between one and three + gotoState("active") + ;playFX(chooser) + + endif + endEVENT +endSTATE + +;=============================================== + +STATE active + EVENT onBeginState() + ; Been triggered. Do stuff. +; Debug.Trace("Entered active state - picked: " + chooser) + if chooser == 1 + self.PlayAnimation("PlayAnim01") + mySFX.play(self) + wait(0.5) + placeAtMe(FallingDustExplosion01) + wait(3.5) + self.PlayAnimation("PlayAnim02") + elseif chooser == 2 + self.PlayAnimation("PlayAnim02") + mySFX.play(self) + elseif chooser == 3 + self.PlayAnimation("PlayAnim03") + mySFX.play(self) + endif + gotoState("waiting") + + endEVENT +endSTATE + + +STATE waiting + EVENT onBeginState() + rndWaitTimer = RandomInt(10,30) +; Debug.Trace("Entered wating state - waiting for " + rndWaitTimer + " seconds") + wait(rndWaitTimer) ; sit around for 1-5 seconds + gotoState("latent") +; Debug.Trace("Should be ready to trigger") + endEVENT +endSTATE + + diff --git a/source/scripts/fxdwarvencenturionscript.psc b/source/scripts/fxdwarvencenturionscript.psc new file mode 100644 index 00000000..61af39c3 --- /dev/null +++ b/source/scripts/fxdwarvencenturionscript.psc @@ -0,0 +1,47 @@ +Scriptname FXDwarvenCenturionSCRIPT extends ActiveMagicEffect +{Add the fx art to the dwarven centurion, sphere,and spider. There are tests for properties being filler since not all three have three addons.} + +import utility +import form + +;=============================================== +actor selfRef +VisualEffect Property FXDwarvenCenturion Auto +VisualEffect Property FXDwarvenCenturionArm01 Auto +VisualEffect Property FXDwarvenCenturionArm02 Auto +int test + + EVENT OnEffectStart(Actor Target, Actor Caster) + selfRef = caster + if (selfRef.GetSleepState() == 3) +; Debug.Trace("Dwarven cent is sleeping! 3") + selfRef.PlaySubGraphAnimation( "StopEffect" ) + else + FXDwarvenCenturion.Play(selfRef, -1) + FXDwarvenCenturionArm01.Play(selfRef, -1) + FXDwarvenCenturionArm02.Play(selfRef, -1) + endIf + ENDEVENT + + Event OnGetUp(ObjectReference akFurniture) +; Debug.Trace("Dwarven cent just got up from " ) + FXDwarvenCenturion.Play(selfRef, -1) + FXDwarvenCenturionArm01.Play(selfRef, -1) + FXDwarvenCenturionArm02.Play(selfRef, -1) + selfRef.PlaySubGraphAnimation( "AutoReset" ) + endEvent + + Event OnEffectFinish(Actor akTarget, Actor akCaster) + FXDwarvenCenturion.Stop(selfRef) + FXDwarvenCenturionArm01.Stop(selfRef) + FXDwarvenCenturionArm02.Stop(selfRef) + ENDEVENT + + EVENT onDeath(actor myKiller) + selfRef.PlaySubGraphAnimation( "StopEffect" ) + wait(8.0) + FXDwarvenCenturion.Stop(selfRef) + FXDwarvenCenturionArm01.Stop(selfRef) + FXDwarvenCenturionArm02.Stop(selfRef) + ENDEVENT + \ No newline at end of file diff --git a/source/scripts/fxdwarvenspherescript.psc b/source/scripts/fxdwarvenspherescript.psc new file mode 100644 index 00000000..af9be74b --- /dev/null +++ b/source/scripts/fxdwarvenspherescript.psc @@ -0,0 +1,26 @@ +Scriptname FXDwarvenSphereScript extends ActiveMagicEffect +{Attached dwarven sphere fx} + +import utility +import form + +;=============================================== +actor selfRef +VisualEffect Property FXDwarvenSphereEffect Auto + + EVENT OnEffectStart(Actor Target, Actor Caster) + selfRef = caster + FXDwarvenSphereEffect.Play(selfRef, -1) + ENDEVENT + + Event OnEffectFinish(Actor akTarget, Actor akCaster) + FXDwarvenSphereEffect.Stop(selfRef) + ENDEVENT + + EVENT onDeath(actor myKiller) + selfRef.PlaySubGraphAnimation( "StopEffect" ) + wait(4.0) + FXDwarvenSphereEffect.Stop(selfRef) + ENDEVENT + + \ No newline at end of file diff --git a/source/scripts/fxdwarvenspiderscript.psc b/source/scripts/fxdwarvenspiderscript.psc new file mode 100644 index 00000000..6347e9fa --- /dev/null +++ b/source/scripts/fxdwarvenspiderscript.psc @@ -0,0 +1,30 @@ +Scriptname FXDwarvenSpiderSCRIPT extends ActiveMagicEffect +{Add the fx art to the dwarven centurion, sphere,and spider. There are tests for properties being filler since not all three have three addons.} + +import utility +import form + +;=============================================== + +Actor selfRef +Keyword Property DLC1LDAetherialSummon Auto +VisualEffect Property FXDwarvenSpiderEffect Auto +Explosion Property ExplosionDwarvenSpider Auto + + EVENT OnEffectStart(Actor Target, Actor Caster) + selfRef = caster + FXDwarvenSpiderEffect.Play(selfRef, -1) + ENDEVENT + + Event OnEffectFinish(Actor akTarget, Actor akCaster) + FXDwarvenSpiderEffect.Stop(selfRef) + ENDEVENT + + EVENT onDying(actor myKiller) + if (selfRef.GetLevel() > 7 && !selfRef.IsCommandedActor() && !selfRef.HasKeyword(DLC1LDAetherialSummon)) + selfRef.PlaySubGraphAnimation( "StopEffect" ) + FXDwarvenSpiderEffect.Stop(selfRef) + selfRef.placeAtMe(ExplosionDwarvenSpider) + EndIf + ENDEVENT + \ No newline at end of file diff --git a/source/scripts/fxgreybeardshoutscript.psc b/source/scripts/fxgreybeardshoutscript.psc new file mode 100644 index 00000000..f9126657 --- /dev/null +++ b/source/scripts/fxgreybeardshoutscript.psc @@ -0,0 +1,87 @@ +Scriptname FXGreybeardShoutScript extends ObjectReference +{automatically plays animation when it loads 3D} + +auto State waiting + + event OnLoad() + ; when loaded, animate + gotoState("playing") + PlayAnimation("Play") + ; TEST - try moving sound here + SoundEnableMarker.Enable() + RegisterForAnimationEvent(self, "End") ; play animation complete + endEvent + +endState + +state playing + + Event OnAnimationEvent(ObjectReference akSource, string asEventName) + +; debug.trace(self + "OnAnimationEvent() recieved " + asEventName) + + if asEventName == "End" +; SoundEnableMarker.Enable() + utility.wait(3) + WordTrigger.Enable() + gotoState("waiting") + EndIf + EndEvent + + ; patch 1.9: + event OnCellDetach() + debug.trace(self + "playing: OnCellDetach - enable trigger") + WordTrigger.Enable() + gotoState("waiting") + endEvent + +endState + +function GoAway() +; debug.trace(self + "GoAway()") + while getState() =="playing" + ; do nothing +; debug.trace(self + " ... waiting for Play anim to finish...") + utility.wait(1) + endWhile + gotoState("goingaway") + LearnWordFadeLoop02.ApplyCrossfade(0.5) + PlayAnimation("Away") + utility.wait(1.5) + ImageSpaceModifier.RemoveCrossFade(0.5) +endFunction + +state goingaway + + Event OnAnimationEvent(ObjectReference akSource, string asEventName) + +; debug.trace(self + "OnAnimationEvent() recieved " + asEventName) + + if asEventName == "End" + gotoState("done") + ; TEST - try not waitingn at all... +; utility.wait(3) + ; disable the sounds + SoundEnableMarker.Disable() + EndIf + EndEvent + +endState + +state done + ; do nothing + event OnUnload() + disable() + endEvent +endState + +ObjectReference Property WordTrigger Auto +{trigger box for learning the word} + +ObjectReference Property SoundEnableMarker Auto +{enable marker for associated sounds} + + + + +ImageSpaceModifier Property LearnWordFadeLoop02 Auto diff --git a/source/scripts/fxmg07dogscript.psc b/source/scripts/fxmg07dogscript.psc new file mode 100644 index 00000000..774a83ad --- /dev/null +++ b/source/scripts/fxmg07dogscript.psc @@ -0,0 +1,30 @@ +Scriptname FXMG07DogScript extends ActiveMagicEffect +{Adds fx to the dog in mg07} + +import utility +import form + +;=============================================== + +ObjectReference selfRef + +VisualEffect Property FXMG07DogEyeGlowEffect Auto +VisualEffect Property FXMG07DogDarkeningEffect Auto + + + EVENT OnEffectStart(Actor Target, Actor Caster) + selfRef = caster + FXMG07DogEyeGlowEffect.Play(selfRef, -1) + FXMG07DogDarkeningEffect.Play(selfRef, -1) + ENDEVENT + + Event OnEffectFinish(Actor akTarget, Actor akCaster) + FXMG07DogEyeGlowEffect.Stop(selfRef) + FXMG07DogDarkeningEffect.Stop(selfRef) + ENDEVENT + + EVENT onDying(actor myKiller) + FXMG07DogEyeGlowEffect.Stop(selfRef) + FXMG07DogDarkeningEffect.Stop(selfRef) + ENDEVENT + \ No newline at end of file diff --git a/source/scripts/fxsetblendvariablescript.psc b/source/scripts/fxsetblendvariablescript.psc new file mode 100644 index 00000000..b5787154 --- /dev/null +++ b/source/scripts/fxsetblendvariablescript.psc @@ -0,0 +1,50 @@ +Scriptname FXSetBlendVariableScript extends ObjectReference +{Sets the blend varaible for this fx on load} + +float Property myfToggleBlend auto +{defaults to zero set from 0-1} +float Property myfToggleBlendRageMin = 0.0 auto +{Randomrange min for when makeRandom is used} +float Property myfToggleBlendRageMax = 1.0 auto +{Randomrange max for when makeRandom is used} +int Property makeRandom auto +{set to 1 to make the blend variable randomly set itself} +int Property updateRandomOverTime auto +{set to 1 to make the blend variable randomly change after the waitTime only matters if makeRandom is set to 1} +float Property waitTimeMin = 1.0 auto +{time to wait before changing myfToggleBlend randomly} +float Property waitTimeMax = 0.0 auto +{max amount to add to waitTime randomly} + +float myRandom +float myWaitTime +int doWhileLoop + + + + Event OnLoad() + ;See if we will set blend variable randomly, randomly over time, or once based on input + if makeRandom > 0 && updateRandomOverTime == 0 + myRandom = utility.RandomFloat(myfToggleBlendRageMin,myfToggleBlendRageMax) + SetAnimationVariableFloat("fToggleBlend", myRandom) + elseif makeRandom > 0 && updateRandomOverTime > 0 + doWhileLoop = 1 + else + SetAnimationVariableFloat("fToggleBlend", myfToggleBlend) + endif + ;Loop to change variable over time + while doWhileLoop == 1 + myRandom = utility.RandomFloat(myfToggleBlendRageMin,myfToggleBlendRageMax) + SetAnimationVariableFloat("fToggleBlend", myRandom) + myWaitTime = utility.RandomFloat(waitTimeMin,waitTimeMax) + utility.wait(myWaitTime) + endWhile + endEvent + + Event OnUnLoad() + ;Stop while loop for random over time when unloaded + if doWhileLoop == 1 + doWhileLoop = 0 + endIf + endEvent + diff --git a/source/scripts/fxshadowmereemergescript.psc b/source/scripts/fxshadowmereemergescript.psc new file mode 100644 index 00000000..a48ab812 --- /dev/null +++ b/source/scripts/fxshadowmereemergescript.psc @@ -0,0 +1,67 @@ +Scriptname FXShadowmereEmergeScript extends ObjectReference +{Shadowmere: rise from your grave!} + +Import Weather +Import Utility + +Actor property myShadowmereRef auto +{shadowmere ref to fade in} +Weather property WeatherForm auto +{Creepy weather to play during the sequence} +ObjectReference Property ShadowmerePoolMistWhite Auto +{Whit mist usually around the pool} +ObjectReference Property ShadowmerePoolMistBlack Auto +{black mist around the pool durig the fade in sequence} +ObjectReference Property ShadowmereLightRef Auto +{Bright blue light turned on during the sequence} +Armor Property HorseSaddleShadowmere Auto +int cleanupTime + + + Event OnLoad() ;Once the FXShadowmereEmerge activator is emnabled this load block should run and set the stage for shadomeres arrival + ;Set scary weather on + WeatherForm.SetActive(true) + ;Turn on blue light ref + ShadowmereLightRef.enable() + ;Hide white mist and show black mist around pool during sequence + ShadowmerePoolMistBlack.enable() + ShadowmerePoolMistWhite.disable() + EndEvent + + Event OnActivate(ObjectReference akActionRef); When the player is in the sweet spot trigger the fade it sequence by activating FXShadowmereEmer + ;Enable shadowmere but make him invisible by running his skinGone animation + myShadowmereRef.enable() + while (myShadowmereRef.Is3DLoaded()) == false + wait(0.05) + endWhile + myShadowmereRef.unequipItem(HorseSaddleShadowmere) + myShadowmereRef.PlaySubGraphAnimation( "SkinGone" ) + ;Play the bubble and smoke fx on the pool + PlayAnimation("PlayAnim01") + wait(3.0) + ;fade in shadowfax + myShadowmereRef.moveTo(self) + myShadowmereRef.PlaySubGraphAnimation( "SkinFadeIn" ) + wait(5.0) + myShadowmereRef.equipItem(HorseSaddleShadowmere) + wait(10.0) + ;Turn off creepy weather + ReleaseOverride() + cleanupTime = 1 + endEvent + + Event OnUnLoad() + ;If cleanup time run the following + if cleanupTime == 1 + ;Switch back to regular mist + ShadowmerePoolMistBlack.disable(true) + ShadowmerePoolMistWhite.enable(true) + ;disable the light when the player in not around since it will pop + ShadowmereLightRef.disable(true) + ;disable myself since i am a bunch of invisible art. + self.disable() + self.delete() + endIf + endEvent + + \ No newline at end of file diff --git a/source/scripts/fxskeletonnecroscript.psc b/source/scripts/fxskeletonnecroscript.psc new file mode 100644 index 00000000..1221f689 --- /dev/null +++ b/source/scripts/fxskeletonnecroscript.psc @@ -0,0 +1,34 @@ +Scriptname FXSkeletonNecroScript extends ActiveMagicEffect +{handles the fx for the necro skeleton} + +VisualEffect Property FXNecroSkeletonMultiEffect auto +VisualEffect Property FXSkeletonNecroEyeGlowEffect auto +EffectShader Property SkeletonNecroDeathFXS auto +Activator property AshPileObject auto +{The object we use as a pile.} +Actor selfRef + + EVENT OnEffectStart(Actor Target, Actor Caster) + selfRef = caster + FXNecroSkeletonMultiEffect.play(selfRef, -1) + FXSkeletonNecroEyeGlowEffect.play(selfRef, -1) + ENDEVENT + + Event OnEffectFinish(Actor akTarget, Actor akCaster) + FXNecroSkeletonMultiEffect.Stop(selfRef) + FXSkeletonNecroEyeGlowEffect.Stop(selfRef) + ENDEVENT + + EVENT OnDying(actor myKiller) + FXNecroSkeletonMultiEffect.stop(selfRef) + FXSkeletonNecroEyeGlowEffect.stop(selfRef) + SkeletonNecroDeathFXS.play(selfRef) + + selfRef.SetCriticalStage(selfRef.CritStage_DisintegrateStart) + selfRef.AttachAshPile(AshPileObject) + + utility.wait(2) + selfRef.SetAlpha (0.0) + selfRef.SetCriticalStage(selfRef.CritStage_DisintegrateEnd) + ENDEVENT + \ No newline at end of file diff --git a/source/scripts/fxsovengardescript.psc b/source/scripts/fxsovengardescript.psc new file mode 100644 index 00000000..bcb56502 --- /dev/null +++ b/source/scripts/fxsovengardescript.psc @@ -0,0 +1,17 @@ +Scriptname FXSovengardeSCRIPT extends ActiveMagicEffect +{Puts the fx on the heavenly people of sovengarde} + +VisualEffect Property FXSovengardeGlowEffect Auto +EffectShader Property SovengardeFXS Auto +Actor selfRef +ObjectReference myGlow + + EVENT OnEffectStart(Actor Target, Actor Caster) + selfRef = caster + ;float myScale = selfRef.getScale() +; ;debug.trace("my scale is" + myScale) + myGlow = FXSovengardeGlowEffect.play(selfRef, -1) + ;myGlow.setScale(myScale) + SovengardeFXS.Play(selfRef) + EndEvent + \ No newline at end of file diff --git a/source/scripts/fxtriggerambfx.psc b/source/scripts/fxtriggerambfx.psc new file mode 100644 index 00000000..513b8328 --- /dev/null +++ b/source/scripts/fxtriggerambfx.psc @@ -0,0 +1,31 @@ +Scriptname FXtriggerAmbFX extends ObjectReference +{executes when someone walks through the cobweb wall or other similar amb fx with triggers} + +activator Property TriggerPlacedFX auto +sound property TriggeredSound auto + int property oneTimeTrigger auto +int broken = 0 +objectReference myFX + +EVENT ONTRIGGERENTER(ObjectReference akActionRef) + IF broken == 0 + if oneTimeTrigger > 0 + broken = 1 + endif + self.SetAnimationVariableFloat("fToggleBlend", 1) + if (TriggerPlacedFX) + myFX = self.placeatme(TriggerPlacedFX, 1) + endif + if (TriggeredSound) + int instanceID = TriggeredSound.Play(Self) + endif + utility.wait (10.0) + myFX.disable() + endif + + IF broken == 1 + utility.wait(3.0) + myFX.disable() + broken = 2 + endIf +ENDEVENT diff --git a/source/scripts/hangedmanscript.psc b/source/scripts/hangedmanscript.psc new file mode 100644 index 00000000..978f7c37 --- /dev/null +++ b/source/scripts/hangedmanscript.psc @@ -0,0 +1,29 @@ +Scriptname hangedManScript extends objectReference +{Script for noose ropes. Point to an attach dummy and a corpse} + +objectReference property nooseDummy auto +{Point to a rigidBodyDummy placed at the end of the rope.} +objectreference property corpse auto +{the hung person} +explosion property fakeForceBallNudge auto + +bool shotDown + + +EVENT onLoad() + ; this gets the guy actually hanging when the 3D is loaded up. + if shotDown == FALSE + ;game.addHavokBallAndSocketConstraint(corpse,"NPC Neck [Neck]",nooseDummy,"AttachDummy",0,0,16) + game.addHavokBallAndSocketConstraint(corpse,"NPC Neck [Neck]",self,"JointHelper01",0,0,16) + endif +endEVENT + + +EVENT onHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) +; debug.trace("Noose Rope Hit by: "+akAggressor) +; debug.trace("Noose Rope Hit by: "+akProjectile) +; debug.trace("Noose Rope Hit by: "+akSource) + game.removeHavokConstraints(corpse,"NPC Neck [Neck]",self,"JointHelper01") + nooseDummy.placeatme(fakeForceBallNudge) + shotDown == TRUE +endEVENT diff --git a/source/scripts/hardworkerwoodscript.psc b/source/scripts/hardworkerwoodscript.psc new file mode 100644 index 00000000..0e216b1d --- /dev/null +++ b/source/scripts/hardworkerwoodscript.psc @@ -0,0 +1,12 @@ +Scriptname HardWorkerWoodScript extends ObjectReference + + +Event OnAnimationEvent(ObjectReference akSource, string asEventName) + if asEventName == "AddToInventory" + AchievementsQuest.IncHardWorker(1) + + endif +endEvent + + +AchievementsScript Property AchievementsQuest Auto \ No newline at end of file diff --git a/source/scripts/hazardbase.psc b/source/scripts/hazardbase.psc new file mode 100644 index 00000000..f697ac21 --- /dev/null +++ b/source/scripts/hazardbase.psc @@ -0,0 +1,164 @@ +scriptName HazardBase extends objectReference +; +; +;============================================ +import utility + +int property damage auto hidden +int property soundLevel = 10 auto +int property trapPushBack auto +sound property TrapHitSound auto +weapon property hitFX auto +ammo property hitFXAmmo auto +int property trapLevel = 1 auto +bool isWaitingToEvaluate = False +float property staggerAmount = 0.0 auto +bool property CheckAngle = false auto +{if true this will check the angle of the actors velocity to the "up" vector of the trap + default == False} + + +auto State CanHit + + Event OnTrapHit(ObjectReference akTarget, float afXVel, float afYVel, float afZVel, float afXPos, float afYPos, float afZPos, int aeMaterial, bool abInitialHit, int aeMotionType) +; debug.Trace(self + ": TrapHit") +; debug.Trace(self + ": XYZ = (" + afXPos + "," + afYPos + "," +afZPos + ")") + if !CheckAngle + doLocalHit(akTarget, afXVel, afYVel, afZVel, afXPos, afYPos, afZPos, aeMaterial, abInitialHit, aeMotionType) + else + if isAngleAcceptable(afXVel, afYVel, afZVel) + doLocalHit(akTarget, afXVel, afYVel, afZVel, afXPos, afYPos, afZPos, aeMaterial, abInitialHit, aeMotionType) + endif + endif + endEvent + + + Event OnTrapHitStart(ObjectReference akTarget, float afXVel, float afYVel, float afZVel, float afXPos, float afYPos, float afZPos, int aeMaterial, bool abInitialHit, int aeMotionType) +; debug.Trace(self + ": TrapHitStart") +; debug.Trace(self + ": XYZ = (" + afXPos + "," + afYPos + "," +afZPos + ")") + if !CheckAngle + doLocalHit(akTarget, afXVel, afYVel, afZVel, afXPos, afYPos, afZPos, aeMaterial, abInitialHit, aeMotionType) + else + if isAngleAcceptable(afXVel, afYVel, afZVel) + doLocalHit(akTarget, afXVel, afYVel, afZVel, afXPos, afYPos, afZPos, aeMaterial, abInitialHit, aeMotionType) + endif + endif + endEvent +EndState + +State CannotHit +endState + +event onLoad() + ResolveLeveledDamage() ;set damage appropriate to player level +endEvent + +event onUpdate() + unRegisterForUpdate() + ;EvaluateStoredRefs() + isWaitingToEvaluate = FALSE +endEvent + +function doLocalHit(ObjectReference akTarget, float afXVel, float afYVel, float afZVel, float afXPos, float afYPos, float afZPos, int aeMaterial, bool abInitialHit, int aeMotionType) + akTarget.ProcessTrapHit(self, damage, trapPushBack, afXVel, afYVel, afZVel, afXPos, afYPos, afZPos, aeMaterial, staggerAmount) +; debug.Trace(self + " has hit " + akTarget) + TrapHitSound.play( self as ObjectReference) ;play hit sound + hitFX.fire(self, hitFxAmmo) + CreateDetectionEvent(akTarget as actor, soundLevel) ; creates a detection event +endFunction + + + +bool function isAngleAcceptable(float afXVel, float afYVel, float afZVel) + float maxZVelocity = 1.0 + float minZVelocity = 0.3 + ; float selfX + ; float selfY + ; float selfZ + ; float selfNodeX + ; float selfNodeY + ; float selfNodeZ + + + + ; float dotProduct + ; dotProduct = sqrt() + ; if acos(MAXANGLE) < dotProduct + +; debug.trace (self + ": X velocity = " + afXVel) +; debug.trace (self + ": Y velocity = " + afYVel) +; debug.trace (self + ": Z velocity = " + afZVel) + + float absoluteZ = (math.abs(afZVel)) + float absoluteY = math.abs(afYVel) + float absoluteX = math.abs(afXVel) + if absoluteZ >= maxZVelocity + return true + elseif absoluteZ >= minZVelocity + if (absoluteZ * (0.6)) >= absoluteY + return True + elseif (absoluteZ * (0.6)) >= absoluteX + Return True + else + return False + endif + else + return false + endif +endFunction + +;====================================================== + + +int property LvlThreshold1 auto +int property LvlDamage1 auto +int property LvlThreshold2 auto +int property LvlDamage2 auto +int property LvlThreshold3 auto +int property LvlDamage3 auto +int property LvlThreshold4 auto +int property LvlDamage4 auto +int property LvlThreshold5 auto +int property LvlDamage5 auto +int property LvlDamage6 auto + +;int Function ResolveLeveledDamage (int damage) +Function ResolveLeveledDamage() + int damageLevel + damageLevel = CalculateEncounterLevel(TrapLevel) + + damage = LvlDamage1 + + if (damageLevel > LvlThreshold1 && damageLevel <= LvlThreshold2) + damage = LvlDamage2 + ;Trace("damage threshold =") + ;Trace("2") + endif + if (damageLevel > LvlThreshold2 && damageLevel <= LvlThreshold3) + damage = LvlDamage3 + ;Trace("damage threshold =") + ;Trace("3") + endif + if (damageLevel > LvlThreshold3 && damageLevel <= LvlThreshold4) + damage = LvlDamage4 + ;Trace("damage threshold =") + ;Trace("4") + endif + if (damageLevel > LvlThreshold4 && damageLevel <= LvlThreshold5) + damage = LvlDamage5 + ;Trace("damage threshold =") + ;Trace("5") + endif + if (damageLevel > LvlThreshold5) + damage = LvlDamage6 + ;Trace("damage threshold =") + ;Trace("6") + endif + + ;Trace("damage =") + ;Trace(damage) + + ;return damage +EndFunction + + \ No newline at end of file diff --git a/source/scripts/helgenrandomsoundscript.psc b/source/scripts/helgenrandomsoundscript.psc new file mode 100644 index 00000000..b1256088 --- /dev/null +++ b/source/scripts/helgenrandomsoundscript.psc @@ -0,0 +1,129 @@ +Scriptname HelgenRandomSoundScript extends ObjectReference +{While the player is in trigger, pick from locations to play these sounds} + +import debug +import utility + +Sound property mySound01 auto +{the sound to play} + +Sound property mySound02 auto +{the sound to play} + +ObjectReference property mySoundOrigin01 auto +{the reference to play the sound from} + +ObjectReference property mySoundOrigin02 auto +{the reference to play the sound from} + +ObjectReference property mySoundOrigin03 auto +{the reference to play the sound from} + +float property fCameraShake01 auto +{camera shake intensity for close roar} + +float property fCameraShake02 auto +{camera shake intensity for distant roar} + +float property fduration01 auto +{camera shake duration for close roar} + +float property fduration02 auto +{camera shake duration for distant roar} + +float property fLIntensity01 auto +{shake left intensity for close roar} + +float property fLIntensity02 auto +{shake left intensity for distant roar} + +float property fRIntensity01 auto +{shake right intensity for close roar} + +float property fRIntensity02 auto +{shake right intensity for distant roar} + +int property maxTimer = 30 auto +{default - 30, max timer for how long to wait between sounds} + +int property minTimer = 20 auto +{default - 20, min timer for how long to wait between sounds} + +bool inTrigger = false +bool busy = false +int iInTrigger = 0 + +;************************************ + +auto State playSound + Event onTriggerEnter (ObjectReference triggerRef) + Actor actorRef = triggerRef as Actor + if (actorRef == game.getPlayer()) + ;inTrigger = true + iInTrigger += 1 + RegisterForSingleUpdate(0.5) + endif + endEvent + + Event onTriggerLeave (ObjectReference triggerRef) + Actor actorRef = triggerRef as Actor + if (actorRef == game.getPlayer()) + ;inTrigger = false + iInTrigger -= 1 + endif + endEvent +endState + +;************************************ + +Event onUpdate() + ;while(inTrigger && !busy) + while((iInTrigger > 0) && !busy) + busy = true + int myTimer = RandomInt(minTimer, maxTimer) + int myOrigin = RandomInt(1,3) + + ; // PHILS CHANGE // + ;int mySound = RandomInt(1,2) + int mySound = 2 + ; // PHILS CHANGE // + + if(myOrigin == 1) + if(mySound == 1) + mySound01.play(mySoundOrigin01) + game.shakeCamera(NONE, fCameraShake01) + game.shakeController(fLIntensity01, fRIntensity01, fduration01) + elseif (mySound == 2) + mySound02.play(mySoundOrigin01) + game.shakeCamera(NONE, fCameraShake02) + game.shakeController(fLIntensity02, fRIntensity02, fduration02) + endif + elseif(myOrigin == 2) + if(mySound == 1) + mySound01.play(mySoundOrigin02) + game.shakeCamera(NONE, fCameraShake01) + game.shakeController(fLIntensity01, fRIntensity01, fduration01) + elseif (mySound == 2) + mySound02.play(mySoundOrigin02) + game.shakeCamera(NONE, fCameraShake02) + game.shakeController(fLIntensity02, fRIntensity02, fduration02) + endif + elseif(myOrigin == 3) + if(mySound == 1) + mySound01.play(mySoundOrigin03) + game.shakeCamera(NONE, fCameraShake01) + game.shakeController(fLIntensity01, fRIntensity01, fduration01) + elseif (mySound == 2) + mySound02.play(mySoundOrigin03) + game.shakeCamera(NONE, fCameraShake02) + game.shakeController(fLIntensity02, fRIntensity02, fduration02) + endif + endif + + wait(mytimer as float) + busy = false + endWhile + +endEvent + +;************************************ diff --git a/source/scripts/icewraithparticlesscript.psc b/source/scripts/icewraithparticlesscript.psc new file mode 100644 index 00000000..3d5dcec4 --- /dev/null +++ b/source/scripts/icewraithparticlesscript.psc @@ -0,0 +1,67 @@ +Scriptname IceWraithParticlesSCRIPT extends ActiveMagicEffect +{Particles to auto add to ice wraith} + +;=============================================== + +import utility +import actor +import form +;=============================================== +Actor selfRef +VisualEffect Property IceWraithParticles01 Auto +Armor Property SkinIceWraithSmokeFins Auto +VisualEffect Property FXIceWraith2ndFormEffect auto + +String property GroundDiveIceHazard auto +String property ChangeForms auto +Spell Property WallOfFrostIceWraith Auto + +Float Property scaleRangeMax = 1.1Auto +Float Property scaleRangeMin = 0.9 Auto +Explosion Property deathExplosion Auto +Activator property AshPileObject auto +{The object we use as a pile.} + + + EVENT OnEffectStart(Actor Target, Actor Caster) + selfRef = caster + selfRef.setScale(RandomFloat(scaleRangeMin, scaleRangeMax)) + IceWraithParticles01.Play(selfRef, -1) + selfRef.EquipItem(SkinIceWraithSmokeFins) + FXIceWraith2ndFormEffect.play(selfRef, -1) + registerForAnimationEvent(selfRef, GroundDiveIceHazard) + registerForAnimationEvent(selfRef, ChangeForms) + ENDEVENT + + Event OnEffectFinish(Actor akTarget, Actor akCaster) + IceWraithParticles01.Stop(selfRef) + selfRef.unEquipItem(SkinIceWraithSmokeFins) + FXIceWraith2ndFormEffect.Stop(selfRef) + ENDEVENT + + EVENT onAnimationEvent(ObjectReference akSource, string asEventName) + if (asEventName == GroundDiveIceHazard) +; debug.trace("event") + WallOfFrostIceWraith.Cast(selfRef) + endif + if (asEventName == ChangeForms) + + selfRef.PlaySubGraphAnimation("SkinFadeOut") + wait(2.0) + selfRef.PlaySubGraphAnimation("SkinFadeIn") + endif + endEVENT + + EVENT onDying(actor myKiller) + IceWraithParticles01.Stop(selfRef) + FXIceWraith2ndFormEffect.stop(selfRef) + selfRef.unEquipItem(SkinIceWraithSmokeFins) + selfRef.placeAtMe(deathExplosion) + + selfRef.SetCriticalStage(selfRef.CritStage_DisintegrateStart) + selfRef.AttachAshPile(AshPileObject) + selfRef.SetAlpha (0.0,True) + wait(1.0) + selfRef.SetCriticalStage(selfRef.CritStage_DisintegrateEnd) + ENDEVENT + diff --git a/source/scripts/itemwithsoudscript.psc b/source/scripts/itemwithsoudscript.psc new file mode 100644 index 00000000..b3361562 --- /dev/null +++ b/source/scripts/itemwithsoudscript.psc @@ -0,0 +1,17 @@ +Scriptname ItemWithSoudScript extends ObjectReference +{Playes a looping sound for items.} + +import sound + +sound property MySoundLoop auto +int soundInstance + +Event onLoad() + ; Sound on + soundInstance = MySoundLoop.play(self) +EndEvent + +Event onUnLoad() + ;Stop sound + StopInstance(soundInstance) +EndEvent diff --git a/source/scripts/magicabsorbfxscript.psc b/source/scripts/magicabsorbfxscript.psc new file mode 100644 index 00000000..f6e14520 --- /dev/null +++ b/source/scripts/magicabsorbfxscript.psc @@ -0,0 +1,92 @@ +ScriptName magicAbsorbFXScript extends ActiveMagicEffect +{Scripted effect for Playing Visual Effects that look like absorb connect beams.} + +import debug +import game + +;======================================================================================; +; PROPERTIES / +;=============/ +ImageSpaceModifier property TrapImod auto +{IsMod applied with this effect} +;sound property TrapSoundFX auto ; create a sound property we'll point to in the editor +;{Sound played when we trap a soul} +VisualEffect property TargetVFX auto +{Visual Effect on Target aiming at Caster} +VisualEffect property CasterVFX auto +{Visual Effect on Caster aming at Target} +; EffectShader property CasterFXS auto +; {Effect Shader on Caster during Soul trap} +; EffectShader property TargetFXS auto +; {Effect Shader on Target during Soul trap} + +Float Property fImodFadeDistance = 2048.0 auto +Float Property fEffectDurationMax = 40.0 auto +{Optional property for controling the time of these effects should they be on a zero duration hit effect Default = 40.0} + +;======================================================================================; +; VARIABLES / +;=============/ + +Float fTDistance +bool bIsFinishing = False + +;======================================================================================; +; EVENTS / +;=============/ + + +Event OnEffectStart(Actor Target, Actor Caster) + + if TrapImod + if Caster != GetPlayer() + ;We want to base the Imod Strength roughly off the distance the Player is from the caster. + fTDistance = GetPlayer().GetDistance(Caster) +; ;debug.trace ("Target Distance is: "+ fTDistance) + fTDistance = (fImodFadeDistance - fTDistance) + if fTDistance <= 0 + TrapImod.apply(0.25) + else + fTDistance = (fTDistance / fImodFadeDistance) + if fTDistance < 0.25 + fTDistance = 0.25 + endif +; ;debug.trace ("Imod Strength is: "+ fTDistance) + TrapImod.apply(fTDistance) + endif + else + TrapImod.apply() ; apply isMod at full strength + endif + endif + if bIsFinishing == False + if TargetVFX + TargetVFX.Play(Target,fEffectDurationMax,Caster) ; Play TargetVFX and aim them at the player + endif + if CasterVFX + CasterVFX.Play(Caster,fEffectDurationMax,Target) + endif + else + if TargetVFX + TargetVFX.Play(Target,2.0,Caster) ; Play TargetVFX and aim them at the player + endif + if CasterVFX + CasterVFX.Play(Caster,2.0,Target) + endif + endif + ; TargetFXS.Play(Target,2) ; Play Effect Shaders + ; CasterFXS.Play(Caster,3) + +EndEvent + +Event OnEffectFinish(Actor Target, Actor Caster) + bIsFinishing = True + if TargetVFX + TargetVFX.Stop(Target) ; Play TargetVFX and aim them at the player + endif + if CasterVFX + CasterVFX.Stop(Caster) + endif +endevent + + + diff --git a/source/scripts/magicattachashpileondeath.psc b/source/scripts/magicattachashpileondeath.psc new file mode 100644 index 00000000..45012052 --- /dev/null +++ b/source/scripts/magicattachashpileondeath.psc @@ -0,0 +1,93 @@ +scriptName magicAttachAshPileOnDeath extends ActiveMagicEffect +{Scripted effect for on death ash pile} + +import debug +import FormList + +;======================================================================================; +; PROPERTIES / +;=============/ + +float property fDelay = 0.75 auto + {time to wait before Spawning Ash Pile} +; float property fDelayAlpha = 1.65 auto +; {time to wait before Setting alpha to zero.} +float property fDelayEnd = 1.65 auto + {time to wait before Removing Base Actor} +float property ShaderDuration = 0.00 auto + {Duration of Effect Shader.} +Activator property AshPileObject auto + {The object we use as a pile.} +EffectShader property MagicEffectShader auto + {The Effect Shader we want.} +Bool property bSetAlphaZero = True auto + {The Effect Shader we want.} +FormList Property ImmunityList auto + {If the target is in this list, they will not be disintegrated.} +Bool property bSetAlphaToZeroEarly = False Auto + {Use this if we want to set the acro to invisible somewhere before the effect shader is done.} + +;======================================================================================; +; VARIABLES / +;=============/ + + +actor Victim +race VictimRace +bool TargetIsImmune = True +; bool DeadAlready = FALSE + +;======================================================================================; +; EVENTS / +;=============/ + +Event OnEffectStart(Actor Target, Actor Caster) + victim = target + ; DeadAlready = Victim.IsDead() + trace("victim == " + victim + ", is this right?") +EndEvent + + +Event OnDying(Actor Killer) + + if ImmunityList == none + TargetIsImmune = False + else + ActorBase VictimBase = Victim.GetBaseObject() as ActorBase + VictimRace = VictimBase.GetRace() + + if ImmunityList.hasform(VictimRace) + TargetIsImmune = True + elseif ImmunityList.hasform(VictimBase) + TargetIsImmune = True + else + TargetIsImmune = False + endif + endif + + if TargetIsImmune == False + trace("victim just died") + ; DeadAlready = true + victim.SetCriticalStage(Victim.CritStage_DisintegrateStart) + ;victim.SetAlpha (0.99,False) + if MagicEffectShader != none + MagicEffectShader.play(Victim,ShaderDuration) + endif + if bSetAlphaToZeroEarly + victim.SetAlpha (0.0,True) + endif + utility.wait(fDelay) + Victim.AttachAshPile(AshPileObject) + ; AshPileRef = AshPileObject + ; AshPileRef.SetAngle(0.0,0.0,(Victim.GetAngleZ())) + utility.wait(fDelayEnd) + if MagicEffectShader != none + MagicEffectShader.stop(Victim) + endif + if bSetAlphaZero == True + victim.SetAlpha (0.0,True) + endif + victim.SetCriticalStage(Victim.CritStage_DisintegrateEnd) + endif + +EndEvent diff --git a/source/scripts/magicbanishscript.psc b/source/scripts/magicbanishscript.psc new file mode 100644 index 00000000..12a2c6d7 --- /dev/null +++ b/source/scripts/magicbanishscript.psc @@ -0,0 +1,61 @@ +scriptName magicBanishScript extends ActiveMagicEffect +{Scripted effect for the Banish Visual Effects} + + + +;======================================================================================; +; PROPERTIES / +;=============/ + +Activator Property ThingToPlace auto +{MANDATORY: Object placed at the start of the spell effect} + +ImageSpaceModifier property ImodFX auto +{OPTIONAL: IsMod applied at the start of the spell effect} + +Int Property SecondsBeforeDelete auto + +;======================================================================================; +; EVENTS / +;=============/ + + +bool function CheckProperties() + if ThingToPlace == None +; debug.trace(self + "Warning: ThingToPlace property is not defined!") + + return false + endif + + return true + +endFunction + +Event OnEffectStart(Actor Target, Actor Caster) + +; ;debug.trace(self + "OnEffectStart() Target:" + Target) + + if checkProperties() == false + return + endif + + + ObjectReference placedEffect + + placedEffect = Target.PlaceAtMe(ThingToPlace) + placedEffect.moveTo(target) + + ;Target.ForceRemoveRagdollFromWorld() + + If ImodFX != None ;Do we have an Imod? + ImodFX.apply() ; apply isMod at full strength + EndIf + + + Utility.wait(SecondsBeforeDelete) + + placedEffect.disable() + placedEffect.delete() + + +EndEvent diff --git a/source/scripts/magicdispelspellonhitscript.psc b/source/scripts/magicdispelspellonhitscript.psc new file mode 100644 index 00000000..c0ee702b --- /dev/null +++ b/source/scripts/magicdispelspellonhitscript.psc @@ -0,0 +1,47 @@ +Scriptname MagicDispelSpellOnHitScript extends ActiveMagicEffect +{This script forces the selected spell(s) to dispel on hit.} + +;======================================================================================; +; PROPERTIES / +;=============/ +spell Property Spell01 auto +spell Property Spell02 auto +spell Property Spell03 auto + + +;======================================================================================; +; VARIABLES / +;=============/ + +Actor TargetActor +bool bWaitLongEnough + +;======================================================================================; +; EVENTS / +;=============/ +Event OnEffectStart(Actor Target, Actor Caster) + TargetActor = Target + utility.wait(0.5) + bWaitLongEnough = true +EndEvent + +Event OnHit(ObjectReference akAggressor, Form akWeapon, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + + if bWaitLongEnough + bWaitLongEnough = False + if Spell01 + TargetActor.dispelspell(Spell01) + endif + + if Spell02 + TargetActor.dispelspell(Spell02) + endif + + if Spell03 + TargetActor.dispelspell(Spell03) + endif + endif + +endevent + + diff --git a/source/scripts/magiceffectshaderapply.psc b/source/scripts/magiceffectshaderapply.psc new file mode 100644 index 00000000..1b9e3d06 --- /dev/null +++ b/source/scripts/magiceffectshaderapply.psc @@ -0,0 +1,88 @@ +scriptName magicEffectShaderApply extends ActiveMagicEffect +{Scripted magic effect Adding and Removing Effect Shaders} + +;import game +;import debug +import utility +;import sound + +;======================================================================================; +; PROPERTIES / +;=============/ + +EffectShader property EffectShaderFX auto +{main Effect Shader for spell} +EffectShader property EffectShaderFX02 auto +{2nd Effect Shader for spell} +EffectShader property EffectShaderFX03 auto +{3rd Effect Shader for spell} + +Float Property fDuration = 0.1 auto +{How Long does it run, if used?} +Float Property fDelay = 0.0 auto +{Delay the effect add for this amount of time.} +;======================================================================================; +; VARIABLES / +;=============/ + +bool Property bRemove = FALSE auto +{Do we Remove the Effect Manually?} +bool Property bUseDuration = FALSE auto +{Do we Use the duration?} + +;======================================================================================; +; EVENTS / +;=============/ + +Event OnEffectStart(Actor Target, Actor Caster) + if EffectShaderFX + EffectShaderFX.Stop(Target) + endif + if EffectShaderFX02 + EffectShaderFX02.Stop(Target) + endif + if EffectShaderFX03 + EffectShaderFX03.Stop(Target) ;Kill EffectShaderFX from another cast, if running. + endif + + wait(fDelay) + + if bUseDuration + if EffectShaderFX + EffectShaderFX.Play(Target,fDuration) + endif + if EffectShaderFX02 + EffectShaderFX02.Play(Target,fDuration) + endif + if EffectShaderFX03 + EffectShaderFX03.Play(Target,fDuration) + endif + else + if EffectShaderFX + EffectShaderFX.Play(Target,-1.0) + endif + if EffectShaderFX02 + EffectShaderFX02.Play(Target,-1.0) + endif + if EffectShaderFX03 + EffectShaderFX03.Play(Target,-1.0) + endif + endif + +EndEvent + +Event OnEffectFinish(Actor Target, Actor Caster) + + if bRemove + if EffectShaderFX + EffectShaderFX.Stop(Target) + endif + if EffectShaderFX02 + EffectShaderFX02.Stop(Target) + endif + if EffectShaderFX03 + EffectShaderFX03.Stop(Target) ;Kill EffectShaderFX from another cast, if running. + endif + endif + +endEvent \ No newline at end of file diff --git a/source/scripts/magiceffectshadersonendscript.psc b/source/scripts/magiceffectshadersonendscript.psc new file mode 100644 index 00000000..c8de1197 --- /dev/null +++ b/source/scripts/magiceffectshadersonendscript.psc @@ -0,0 +1,40 @@ +scriptName magicEffectShadersOnEndScript extends ActiveMagicEffect +{Scripted magic effect for applying up to 3 Effect Shaders when the Spell Ends.} + +import utility +import game +;======================================================================================; +; PROPERTIES / +;=============/ + +EffectShader property EffectShaderFX01 auto +{main Effect Shader for spell} +EffectShader property EffectShaderFX02 auto +{2nd Effect Shader for spell} +EffectShader property EffectShaderFX03 auto +{3rd Effect Shader for spell} + +Float Property fDuration = 0.1 auto +{How long do the shaders run. (Default = 0.1)} + +;======================================================================================; +; VARIABLES / +;=============/ + + + +;======================================================================================; +; EVENTS / +;=============/ + +Event OnEffectFinish(Actor Target, Actor Caster) + if EffectShaderFX01 != None + EffectShaderFX01.Play(Target,fDuration) + endif + if EffectShaderFX02 != None + EffectShaderFX02.Play(Target,fDuration) + endif + if EffectShaderFX03 != None + EffectShaderFX03.Play(Target,fDuration) + endif +EndEvent diff --git a/source/scripts/magicimodbasicscript.psc b/source/scripts/magicimodbasicscript.psc new file mode 100644 index 00000000..5fc48029 --- /dev/null +++ b/source/scripts/magicimodbasicscript.psc @@ -0,0 +1,45 @@ +scriptName MagicImodBasicScript extends ActiveMagicEffect +{Scripted effect fo one basic Imod, nothing flashy.} + +;======================================================================================; +; PROPERTIES / +;=============/ + +Bool Property bPlayerOnly = False auto +{Set this if you only want this Imod to play if the player is the spell caster.} +ImageSpaceModifier property ImodFX auto +{main isMod for spell} +Float Property fImodStrength = 1.0 auto +{IsMod Strength from 0.0 to 1.0} + +Bool bIsOkToPlay = true +actor TargetActor +actor CasterActor +;======================================================================================; +; EVENTS / +;=============/ + + +Event OnEffectStart(Actor Target, Actor Caster) + TargetActor = Target + CasterActor = Caster + + if bPlayerOnly + if CasterActor != game.GetPlayer() + bIsOkToPlay = False + endif + endif + + if bIsOkToPlay + ImodFX.remove() ;Kill Imods from another cast, if running. + ImodFX.apply(fImodStrength) ; remove initial FX + endif + + +EndEvent + +Event OnEffectFinish(Actor Target, Actor Caster) + if bIsOkToPlay + ImodFX.remove() + endif +endEvent diff --git a/source/scripts/magicimodbeginloopend.psc b/source/scripts/magicimodbeginloopend.psc new file mode 100644 index 00000000..804aa5c2 --- /dev/null +++ b/source/scripts/magicimodbeginloopend.psc @@ -0,0 +1,70 @@ +scriptName magicImodBeginLoopEnd extends ActiveMagicEffect +{Scripted effect for the Night Eye Spell} + + + +;======================================================================================; +; PROPERTIES / +;=============/ + +Bool Property bPlayerOnly = False auto +{Set this if you only want this Imod to play if the player is the spell caster.} +float property fDelay = 0.83 auto +{time to wait before switching to constant Imod} +ImageSpaceModifier property IntroFX auto +{IsMod applied at the start of the spell effect} +ImageSpaceModifier property LoopFX auto +{main isMod for spell} +ImageSpaceModifier property OutroFX auto +{IsMod applied at the end of the spell effect} +Float Property fImodStrength = 1.0 auto +{IsMod Strength from 0.0 to 1.0} +; sound property IntroSoundFX auto ; create a sound property we'll point to in the editor +; sound property OutroSoundFX auto ; create a sound property we'll point to in the editor + +; Obtain the target of the active fire effect + +Bool bIsOkToPlay = true +bool bIsFinishing = false +actor TargetActor +actor CasterActor +;======================================================================================; +; EVENTS / +;=============/ + + +Event OnEffectStart(Actor Target, Actor Caster) + TargetActor = Target + CasterActor = Caster + + if bPlayerOnly + if CasterActor != game.GetPlayer() + bIsOkToPlay = False + endif + endif + + if bIsOkToPlay + ;int instanceID = IntroSoundFX.play((target as objectReference)) ; play IntroSoundFX sound from my self + IntroFX.remove() + LoopFX.remove() ;Kill Imods from another cast, if running. + OutroFX.remove() + + introFX.apply(fImodStrength) ; apply isMod at full strength + utility.wait(fDelay) ; NOTE - neccessary? + if bIsFinishing == False + ;LoopFX.apply() + introFX.PopTo(LoopFX,fImodStrength) ; remove initial FX + endif + endif + +EndEvent + +Event OnEffectFinish(Actor Target, Actor Caster) + bIsFinishing = True + if bIsOkToPlay + ;int instanceID = OutroSoundFX.play((target as objectReference)) ; play OutroSoundFX sound from my self + introFX.remove() + ;LoopFX.remove() + LoopFX.PopTo(OutroFX,fImodStrength) + endif +endEvent diff --git a/source/scripts/magicimodonplayerhitscript.psc b/source/scripts/magicimodonplayerhitscript.psc new file mode 100644 index 00000000..fd0c6bcf --- /dev/null +++ b/source/scripts/magicimodonplayerhitscript.psc @@ -0,0 +1,43 @@ +scriptName MagicImodOnPlayerHitScript extends ActiveMagicEffect +{Scripted effect play a one off Imod if the player is hit by the spell with optional removal Imod.} + +;======================================================================================; +; PROPERTIES / +;=============/ + +ImageSpaceModifier property OnStartImodFX auto +{main isMod for spell (MUST BE ANIMATED IMOD)} +ImageSpaceModifier property OnFinishImodFX auto +{Optional ending Imod for spell (MUST BE ANIMATED IMOD)} + +Float Property fImodStrength = 1.0 auto +{IsMod Strength from 0.0 to 1.0} + +bool bPlayerOnly +Bool bIsOkToPlay +actor TargetActor +actor CasterActor +;======================================================================================; +; EVENTS / +;=============/ + + +Event OnEffectStart(Actor Target, Actor Caster) + TargetActor = Target + CasterActor = Caster + + if TargetActor == game.GetPlayer() + OnStartImodFX.apply(fImodStrength) + utility.wait(5.0) + bIsOkToPlay = True + endif + +EndEvent + +Event OnEffectFinish(Actor Target, Actor Caster) + if bIsOkToPlay + if OnFinishImodFX + OnFinishImodFX.apply(fImodStrength) + endif + endif +endEvent diff --git a/source/scripts/magicnighteyescript.psc b/source/scripts/magicnighteyescript.psc new file mode 100644 index 00000000..628dd39a --- /dev/null +++ b/source/scripts/magicnighteyescript.psc @@ -0,0 +1,78 @@ +scriptName magicNightEyeScript extends ActiveMagicEffect +{Scripted effect for the Night Eye Spell} + +import GlobalVariable + +;======================================================================================; +; PROPERTIES / +;=============/ + +float property fDelay = 0.83 auto +{time to wait before switching to constant Imod} +ImageSpaceModifier property IntroFX auto +{IsMod applied at the start of the spell effect} +ImageSpaceModifier property MainFX auto +{main isMod for spell} +ImageSpaceModifier property OutroFX auto +{IsMod applied at the end of the spell effect} +Float Property fImodStrength = 1.0 auto +{IsMod Strength from 0.0 to 1.0} +sound property IntroSoundFX auto ; create a sound property we'll point to in the editor +sound property OutroSoundFX auto ; create a sound property we'll point to in the editor +GlobalVariable Property NightEyeTransitionGlobal auto +;MagicEffect Property NightEyeEffect auto +;Spell Property NightEyeDispelEffectSpell auto +; Obtain the target of the active fire effect + +;Actor CasterActor +;======================================================================================; +; EVENTS / +;=============/ + +Event OnEffectStart(Actor Target, Actor Caster) + ;CasterActor = Caster + + ; IntroFX.remove() + ; MainFX.remove() ;Kill Imods from another cast, if running. + ; OutroFX.remove() + + if NightEyeTransitionGlobal.GetValue() == 0.0 + NightEyeTransitionGlobal.setValue(1.0) + int instanceID = IntroSoundFX.play((target as objectReference)) ; play IntroSoundFX sound from my self + introFX.apply(fImodStrength) ; apply isMod at full strength + utility.wait(fDelay) ; NOTE - neccessary? + ;MainFX.apply() + if NightEyeTransitionGlobal.GetValue() == 1.0 + introFX.PopTo(MainFX,fImodStrength) + NightEyeTransitionGlobal.setValue(2.0) + endif + elseif NightEyeTransitionGlobal.GetValue() == 1.0 + introFX.PopTo(MainFX,fImodStrength) + NightEyeTransitionGlobal.setValue(2.0) + self.dispel() + else + self.dispel() + endif + +EndEvent + +; Event OnMagicEffectApply(ObjectReference akCaster, MagicEffect NightEyeEffect) + ; NightEyeDispelEffectSpell.Cast(CasterActor) +; endEvent + +Event OnEffectFinish(Actor Target, Actor Caster) + ; if NightEyeTransitionGlobal.GetValue() == 1.0 + ; utility.wait(fDelay) + ; endif +; ;debug.trace (self + ": We are killing the spell. The Globale is: " + NightEyeTransitionGlobal.GetValue()) + if NightEyeTransitionGlobal.GetValue() == 2.0 + NightEyeTransitionGlobal.setValue(3.0) +; ;debug.trace (self + ": This is a valid outro play, see because 2.0 = " + NightEyeTransitionGlobal.GetValue()) + int instanceID = OutroSoundFX.play((target as objectReference)) ; play OutroSoundFX sound from my self + ;MainFX.remove() + MainFX.PopTo(OutroFX,fImodStrength) + introFX.remove() + NightEyeTransitionGlobal.setValue(0.0) + endif + +endEvent diff --git a/source/scripts/magicplaceactivatorscript.psc b/source/scripts/magicplaceactivatorscript.psc new file mode 100644 index 00000000..5588acb5 --- /dev/null +++ b/source/scripts/magicplaceactivatorscript.psc @@ -0,0 +1,60 @@ +scriptName magicPlaceActivatorScript extends ActiveMagicEffect +{Scripted magic effect Placing and activator and then removing it.} + + + +;======================================================================================; +; PROPERTIES / +;=============/ +activator property PlacedActivator auto +{The name of the Activator we will be placing.} +Explosion property ExplosionRef auto +{The name of the Explosion we will be placing.} +Bool property DeletAtEnd = True auto +{Remove the placed activator when the spell ends? (Default = True)} + + +;======================================================================================; +; VARIABLES / +;=============/ + +objectReference ActivatorRef +bool KeepUpdating = true +form TargetActor + +;======================================================================================; +; EVENTS / +;=============/ + +Event OnEffectStart(Actor Target, Actor Caster) + ActivatorRef = Caster.placeAtMe(PlacedActivator) + TargetActor = Target +; ;debug.trace ("We placed this Activator: " + PlacedActivator + " and cast it as: " + ActivatorRef) + if ExplosionRef != none + ActivatorRef.placeatme(ExplosionRef) + RegisterForSingleUpdate(0.65) + endif +EndEvent + + +Event OnUpdate() + + ActivatorRef.placeatme(ExplosionRef) +; ;debug.trace ("We will now place the explosion: " + ExplosionRef + " at the activator: " + ActivatorRef) + if KeepUpdating == True + RegisterForSingleUpdate(0.65) + endif + +endEvent + + +Event OnEffectFinish(Actor Target, Actor Caster) + KeepUpdating = false + if DeletAtEnd + ActivatorRef.disable() + ActivatorRef.delete() + endif +EndEvent + + + diff --git a/source/scripts/magicplayeffectshaderonhitscript.psc b/source/scripts/magicplayeffectshaderonhitscript.psc new file mode 100644 index 00000000..bb7b5f6b --- /dev/null +++ b/source/scripts/magicplayeffectshaderonhitscript.psc @@ -0,0 +1,31 @@ +Scriptname MagicPlayEffectShaderOnHitScript extends ActiveMagicEffect +{This script plays an effect shader on hit.} + +;======================================================================================; +; PROPERTIES / +;=============/ + +EffectShader property MagicEffectShader auto +{The Effect Shader we want.} +float property ShaderDuration = 0.00 auto +{Duration of Effect Shader.} + +;======================================================================================; +; VARIABLES / +;=============/ + +Actor TargetActor + + +;======================================================================================; +; EVENTS / +;=============/ +Event OnEffectStart(Actor Target, Actor Caster) + TargetActor = Target +EndEvent + +Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + + MagicEffectShader.play(TargetActor,ShaderDuration) + +endevent diff --git a/source/scripts/magicsetactoralphascript.psc b/source/scripts/magicsetactoralphascript.psc new file mode 100644 index 00000000..b26e6125 --- /dev/null +++ b/source/scripts/magicsetactoralphascript.psc @@ -0,0 +1,33 @@ +scriptName magicSetActorAlphaScript extends ActiveMagicEffect +{Scripted effect Setting the Alpha of an Actor and back} + +;======================================================================================; +; PROPERTIES / +;=============/ + + +float property AlphaValue = 1.0 auto +{Alpha Value the target will be faded to.} +Bool property FadeToAlpha = False auto +{Do we fade the alpha to the value over time?} +Bool property DontFadeBack = False auto +{Check this if you do not want to return to normal after the spell ends} + +;======================================================================================; +; EVENTS / +;=============/ + + +Event OnEffectStart(Actor Target, Actor Caster) + If AlphaValue != 1.0 ;Do we have any data? + Target.SetAlpha (AlphaValue, FadeToAlpha) + EndIf +EndEvent + +Event OnEffectFinish(Actor Target, Actor Caster) + if DontFadeBack == False + If AlphaValue != 1.0 ;Do we have any data? + Target.SetAlpha (1.0, FadeToAlpha) + EndIf + endif +EndEvent diff --git a/source/scripts/mg08paralysiseffectscript.psc b/source/scripts/mg08paralysiseffectscript.psc new file mode 100644 index 00000000..2b7addae --- /dev/null +++ b/source/scripts/mg08paralysiseffectscript.psc @@ -0,0 +1,17 @@ +Scriptname MG08ParalysisEffectScript extends ActiveMagicEffect + +Spell Property MG08ParalysisAbility Auto +Quest Property MG08 Auto + + +Event OnEffectStart(Actor AkTarget, Actor akCaster) + + AkTarget.AddSpell(MG08ParalysisAbility) + While MG08.GetStage() < 40 + Utility.Wait(5) +; Debug.Trace(self + "In While Loop") + EndWhile + AkTarget.RemoveSpell(MG08ParalysisAbility) + +EndEvent + diff --git a/source/scripts/movingtrap.psc b/source/scripts/movingtrap.psc new file mode 100644 index 00000000..f4c45a1b --- /dev/null +++ b/source/scripts/movingtrap.psc @@ -0,0 +1,86 @@ +scriptName MovingTrap extends TrapBase +; +; +;This is the base class for a moving trap. +;When a moving trap collides with an actor, it should damage that actor. +;This sets up the mechanics, but behavior will have to be set up on the inherited object. +;================================================================ + +import debug +import utility + +;================================================================ + +bool property isLoaded = True auto hidden +bool property isFiring = False auto hidden + +int property LvlThreshold1 auto +int property LvlDamage1 auto +int property LvlThreshold2 auto +int property LvlDamage2 auto +int property LvlThreshold3 auto +int property LvlDamage3 auto +int property LvlThreshold4 auto +int property LvlDamage4 auto +int property LvlThreshold5 auto +int property LvlDamage5 auto +int property LvlDamage6 auto + +;int Function ResolveLeveledDamage (int damage) +Function ResolveLeveledDamage() + int damageLevel + int damage + damageLevel = CalculateEncounterLevel(TrapLevel) + + damage = LvlDamage1 + + if (damageLevel > LvlThreshold1 && damageLevel <= LvlThreshold2) + damage = LvlDamage2 + ;Trace("damage threshold =") + ;Trace("2") + endif + if (damageLevel > LvlThreshold2 && damageLevel <= LvlThreshold3) + damage = LvlDamage3 + ;Trace("damage threshold =") + ;Trace("3") + endif + if (damageLevel > LvlThreshold3 && damageLevel <= LvlThreshold4) + damage = LvlDamage4 + ;Trace("damage threshold =") + ;Trace("4") + endif + if (damageLevel > LvlThreshold4 && damageLevel <= LvlThreshold5) + damage = LvlDamage5 + ;Trace("damage threshold =") + ;Trace("5") + endif + if (damageLevel > LvlThreshold5) + damage = LvlDamage6 + ;Trace("damage threshold =") + ;Trace("6") + endif + + ;Trace("damage =") + ;Trace(damage) + + ;return damage + hitBase = (self as objectReference) as TrapHitBase + if hitbase + hitBase.damage = damage + endif +EndFunction + +event onCellAttach() + isLoaded = TRUE + if isFiring == True + fireTrap() + endif +EndEvent + +event onCellDetach() +; debug.Trace(self + " has recieved onUnload event") + isLoaded = FALSE +endEvent + + + diff --git a/source/scripts/mqgreybeardabsorbscript.psc b/source/scripts/mqgreybeardabsorbscript.psc new file mode 100644 index 00000000..402e935c --- /dev/null +++ b/source/scripts/mqgreybeardabsorbscript.psc @@ -0,0 +1,113 @@ +Scriptname MQGreybeardAbsorbScript extends Quest +{script allowing Greybeard absorb} + +import Game +import utility + + +; for Greybeard effect +VisualEffect Property FXGreybeardAbsorbEffect Auto +EffectShader Property GreybeardPowerAbsorbFXS Auto +EffectShader Property GreybeardPlayerPowerAbsorbFXS Auto +sound property NPCDragonDeathSequenceWind auto +sound property NPCDragonDeathSequenceExplosion auto + +; for dragon effect +VisualEffect Property DragonAbsorbEffect Auto +VisualEffect Property DragonAbsorbManEffect Auto +EffectShader Property DragonPowerAbsorbFXS Auto + +ObjectReference Property KnockAreaEffectMarker Auto + +; use this for Greybeards +function AbsorbEffect(Actor target, int stageToSet = 0) + + ;Play art and fx shaders on player and targeted grybeard + FXGreybeardAbsorbEffect.Play(target, 7, GetPlayer()) + GreybeardPowerAbsorbFXS.Play(target) + GreybeardPlayerPowerAbsorbFXS.Play(GetPlayer()) + + ;Wait for the art to play + ;Wait(7.0) + ; INSTEAD - break up the 7 seconds: + + ; damage target to simulate absorption + float damage = target.GetActorValue("health")/5 ; use 3 if bleedout looks good + target.DamageActorValue("health", damage) +; KnockAreaEffectMarker.Moveto(target) +; KnockAreaEffectMarker.KnockAreaEffect(0.2, 5) + target.PlayIdle(BracedPainIdle) + + ; Sounds for when the wispy particles being to fly at the player. + NPCDragonDeathSequenceWind.play(target) + NPCDragonDeathSequenceExplosion.play(target) + + wait(2) + target.DamageActorValue("health", damage) +; KnockAreaEffectMarker.Moveto(target) +; KnockAreaEffectMarker.KnockAreaEffect(0.5, 5) +; target.PlayIdle(BracedPainIdle) + + + wait(2) + target.DamageActorValue("health", damage) +; KnockAreaEffectMarker.Moveto(target) +; KnockAreaEffectMarker.KnockAreaEffect(0.8, 5) +; target.PlayIdle(BracedPainIdle) + + wait(2) + target.DamageActorValue("health", damage) +; KnockAreaEffectMarker.Moveto(target) +; KnockAreaEffectMarker.KnockAreaEffect(1.0, 5) +; target.PlayIdle(BracedPainIdle) + + + Wait(1.0) + + ;remove magic shaders + GreybeardPowerAbsorbFXS.Stop(target) + GreybeardPlayerPowerAbsorbFXS.Stop(GetPlayer()) + + ; set stage when finished + if stageToSet > 0 + setstage(stageToSet) + endif + +endFunction + +; use this for Paarthurnax +function DragonAbsorbEffect(Actor target, int stageToSet = 0) + + ;display dragon absorb effect art. One part on dragon one part on player. + DragonAbsorbEffect.Play(target, 8, GetPlayer()) + DragonAbsorbManEffect.Play(GetPlayer(), 8, target) + + ; Sounds for when the wispy particles being to fly at the player. + NPCDragonDeathSequenceWind.play(target) + NPCDragonDeathSequenceExplosion.play(target) + + wait(0.1) + + ; On man power absorb effect shader. + DragonPowerAbsorbFXS.Play(GetPlayer()) + + wait(2) + + wait(4) + + ;Stop fx shader on player showing power absorb. + DragonPowerAbsorbFXS.Stop(GetPlayer()) + + wait(4) + + ; Get rid of art attached to dragon and player showing streaming magic. + DragonAbsorbEffect.Stop(target) + DragonAbsorbManEffect.Stop(GetPlayer()) + + ; set stage when finished + if stageToSet > 0 + setstage(stageToSet) + endif + +endFunction +Idle Property BracedPainIdle Auto diff --git a/source/scripts/mqkilldragonscript.psc b/source/scripts/mqkilldragonscript.psc new file mode 100644 index 00000000..1c7d1e68 --- /dev/null +++ b/source/scripts/mqkilldragonscript.psc @@ -0,0 +1,514 @@ +Scriptname MQKillDragonScript extends Quest Conditional +{holds property and dragon death function, until we have base actor scripts} + +import game +import debug +import utility +import sound + + +;************************************************ +; this is what actually does the death sequence +; change timing and art here +;************************************************ + +;------------------------ADDED FOR DLC2--------------------- +bool Function TryMiraakMakeHisIntroduction(Actor DragonRef) + + RETURN DLC2SoulSteal.TryMiraakMakeHisIntroduction(DragonRef) + +EndFunction + + +bool Function ShouldMiraakAppear(Actor DragonRef) + + RETURN DLC2SoulSteal.ShouldMiraakAppear(DragonRef) + +EndFunction +;---------------------------------------------------------------- + + +function DeathSequence(Actor dragonRef, Actor AbsorbActor = None, bool MiraakAppears = False) +;ADDED "Actor AbsorbActor = none, bool MiraakAppears = false" FOR DLC2 + + ;ADDED FOR DLC2---------------------------------- + if game.getPlayer().isInLocation(DLC2ApocryphaLocation) || game.getPlayer().getWorldSpace() == DLC2ApocryphaWorld + if AbsorbActor == none +; Debug.Trace(self + "Miraak Soul Stealing in Apocrypha Boss Fight") + ;Start an alternate version of the death sequence that gets to the soul absorb faster + MQ06DeathSequence(dragonRef, DLC2MiraakMQ06Ref, false) + return + endif + else + if AbsorbActor == none + AbsorbActor = Game.GetPlayer() + + endif + + if MiraakAppears +; Debug.Trace(self + "Calling DLC2SoulSteal.MiraakAppears()") + DLC2SoulSteal.MiraakAppears(dragonRef) + return + endif + endif + ;------------------------------------------------ + + + if dragonRef.IsInFaction(NoDragonAbsorb) + return + endif + + ; Add Skeleton to dragon's inventory. + dragonRef.AddItem(DragonUnderskin) + + ; Dragon wings particles bits + + FXDragonDeathLHandBits.Play(dragonRef, 12) + FXDragonDeathRHandBits.Play(dragonRef, 12) + + + wait(0.2) + + ;Equip skeleton under skin + dragonRef.EquipItem(DragonUnderskin) + wait(0.5) + dragonRef.PlaySubGraphAnimation("UnderSkinFadeOut") + + ;*** WORLD INTERACTION FUNCTION -- jduvall + WI.PlayerIsCurrentlyAbsorbingPower(dragonRef) + bIsAbsorbing = true + + ; Start effect shader decorating holes in the base skin + DragonHolesFXS.Play(dragonRef) + ; Play disintegrating skin. + dragonRef.PlaySubGraphAnimation( "SkinFadeOut" ) +;;; + ; Play imagespace modifier which is timed to match sequence. + DragonPowerAbsorbISM.Apply() + + ; Sound of dragon carcass first bursts into flames until the flames die off. Must be turned off + int soundInstanceFireID = NPCDragonDeathSequenceFireLPM.play(dragonRef) + + wait(1) + + ;Small bits rising from dragon fx shader. + DragonHolesBitsLiteFXS.Play(dragonRef) + + wait(1) + ;Bigger bits rising from dragon fx shader. + DragonHolesBitsFXS.Play(dragonRef) + + wait(2) + + + + wait(1.75) + ;Play blood fade out if it is there + dragonRef.PlaySubGraphAnimation("BloodFade") + + ; Magic particles on wings + FXDragonDeathRHandFire.Play(dragonRef, 12) + FXDragonDeathLHandFire.Play(dragonRef, 12) + + wait(1.0) + ; magic fire fx shader + DragonHolesMagicFXS.Play(dragonRef) + DragonHolesMagicFXS.Stop(dragonRef);;;;;;;;;;;;;;;;;;;;;;;; + + wait(0.25) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;StopDragon bits fxs + DragonHolesBitsFXS.Stop(dragonRef) + DragonHolesBitsLiteFXS.Stop(dragonRef) + ;Stop holes fx shader now that main dragon skin is un-worn + DragonHolesFXS.Stop(dragonRef) + + ; Play light emitting magic shader on dragon +;; DragonHolesLightFXS.Play(dragonRef) + + wait(1.8) + ;unequipp invisible art + if dragonRef.IsEquipped(DragonBloodHeadFXArmor) == true + dragonRef.unEquipItem(DragonBloodHeadFXArmor) + endif + if dragonRef.IsEquipped(DragonBloodTailFXArmor) == true + dragonRef.unEquipItem(DragonBloodTailFXArmor) + endif + if dragonRef.IsEquipped(DragonBloodWingLFXArmor) == true + dragonRef.unEquipItem(DragonBloodWingLFXArmor) + endif + if dragonRef.IsEquipped(DragonBloodWingRFXArmor) == true + dragonRef.unEquipItem(DragonBloodWingRFXArmor) + endif + + ;display dragon absorb effect art. One part on dragon one part on player. + DragonAbsorbEffect.Play(dragonRef, 8, AbsorbActor) ;***DLC2: CHANGED FROM GetPlayer() to AbsorbActor +;; dragonRef.placeAtME(MAGDragonPowerAbsorbExplosion) + DragonAbsorbManEffect.Play(AbsorbActor, 8, dragonRef) ;***DLC2: CHANGED FROM GetPlayer() to AbsorbActor + + ; Sounds for when the wispy particles being to fly at the player. + NPCDragonDeathSequenceWind.play(dragonRef) + NPCDragonDeathSequenceExplosion.play(dragonRef) + + wait(0.1) + + ; On man power absorb effect shader. + DragonPowerAbsorbFXS.Play(AbsorbActor) ;***DLC2: CHANGED FROM GetPlayer() to AbsorbActor + + + if AbsorbActor == Game.GetPlayer() ;***DLC2 + wait(1) + ; turn off remaining effect bits and magic leak fxshaders + + wait(1) + + Endif + + ; ghost the dragon so you can't hit him + dragonRef.SetGhost(true) + + ;clear any arrows that may have been stuck in dragon + dragonRef.clearExtraArrows() + + +;; + + if AbsorbActor == Game.GetPlayer() ;***DLC2 + wait(4) + else + wait(3) + endif + + ;Stop fx shader on player showing power absorb. + DragonPowerAbsorbFXS.Stop(AbsorbActor) ;***DLC2: CHANGED FROM GetPlayer() to AbsorbActor + + ; End sound of dragon carcass bursting into flames. + StopInstance(soundInstanceFireID) + + ; add lingering smoke and glow to dragon carcass. + DragonHolesSmokeFXS.Play(dragonRef) + + ; Start sound for smoldering dragon + int soundInstanceSmolderID = NPCDragonDeathSequenceSmolderLPM.play(dragonRef) + + + if AbsorbActor == Game.GetPlayer() ;***DLC2 + wait(4) + endif + + ;*** CHANGED FOR DLC2-------------------------------------------------------- + + if AbsorbActor == GetPlayer() + ; increment dragon count + DragonsAbsorbed.value = DragonsAbsorbed.value + 1 + + ; add dragonsoul point to player + AbsorbActor.modActorValue("dragonsouls", VoicePointsReward) ;***DLC2: CHANGED FROM GetPlayer() to AbsorbActor + + ; do this right now for MQ104 dragon: + if !MQ104.GetStageDone(90) && MQ104.IsRunning() +; ; debug.trace(self + " setting MQ104 stage 90") + MQ104.SetStage(90) + endif + + elseif game.getPlayer().isInLocation(DLC2ApocryphaLocation) + DLC2BossBattleScript = DLC2MQ06MiraakAlias as DLC2MQ06MiraakBossBattle + DLC2BossBattleScript.MiraakStealsSoul() + else + ;MIRAAK STOLE THE SOUL!!! + DLC2SoulSteal.FinishStealingSoul() + + endif + + TryMiraakMakeHisIntroduction(DragonRef) + + ;------------------------------------------------------------------------------- + + ; turn off effect shaders for smoldering carcass + DragonHolesSmokeFXS.Stop(dragonRef) + + ; Get rid of art attached to dragon and player showing streaming magic. + DragonAbsorbEffect.Stop(dragonRef) + DragonAbsorbManEffect.Stop(AbsorbActor) ;***DLC2: CHANGED FROM GetPlayer() to AbsorbActor + + if AbsorbActor == Game.GetPlayer() ;***DLC2 + wait(4) + endif + + ;Stop smoldering sound + StopInstance(soundInstanceSmolderID) + + ; put dragon in faction so other quests know player has absorbed power + dragonRef.addtoFaction(MQKillDragonFaction) + + ;Stop light emitting magic shader on dragon + DragonHolesLightFXS.Stop(dragonRef) + + ;*** WORLD INTERACTION FUNCTION -- jduvall + WI.PlayerIsDoneAbsorbingPower(dragonRef) + + dragonRef.EquipItem(SkinDragonHider, true) + + bIsAbsorbing = false + +endFunction + +WIFunctionsScript Property WI Auto +{Pointer to WIFunctionsScript on WI quest. Used to call functions so that the dialogue in the scene in WIDragonKill quest is aware of when the player is aborbing and done absorbing the dragon's power.} + +GlobalVariable Property DragonsAbsorbed Auto + +Armor Property DragonUnderskin Auto + +Faction Property MQKillDragonFaction Auto + +int Property VoicePointsReward = 1 Auto +{how many soul points to give player} + + + +VisualEffect Property DragonAbsorbEffect Auto +VisualEffect Property DragonAbsorbManEffect Auto +VisualEffect Property FXDragonDeathLHandBits Auto +VisualEffect Property FXDragonDeathLHandFire Auto +VisualEffect Property FXDragonDeathRHandBits Auto +VisualEffect Property FXDragonDeathRHandFire Auto +;VisualEffect Property DragonDeadswapHide Auto +;VisualEffect Property DragonDeadswap Auto + +EffectShader Property DragonHolesFXS Auto +EffectShader Property DragonHolesBitsFXS Auto +EffectShader Property DragonHolesBitsLiteFXS Auto +EffectShader Property DragonPowerAbsorbFXS Auto +EffectShader Property DragonHolesSmokeFXS Auto +EffectShader Property DragonHolesMagicFXS Auto +EffectShader Property DragonHolesLightFXS Auto + +ImageSpaceModifier Property DragonPowerAbsorbISM Auto + +sound property NPCDragonDeathSequenceFireLPM auto +sound property NPCDragonDeathSequenceWind auto +sound property NPCDragonDeathSequenceExplosion auto +sound property NPCDragonDeathSequenceSmolderLPM auto + +Armor Property DragonBloodHeadFXArmor Auto +Armor Property DragonBloodTailFXArmor Auto +Armor Property DragonBloodWingLFXArmor Auto +Armor Property DragonBloodWingRFXArmor Auto +Armor Property SkinDragonHider Auto + +Explosion Property MAGDragonPowerAbsorbExplosion Auto + +Faction Property NoDragonAbsorb Auto +{no death sequence if in this faction} + +bool Property bIsAbsorbing Auto Conditional +{true while the absorb sequence is running} + +Quest Property MQ104 Auto + + + + +;Added for DLC------------------------------------------- +;Everything below this is a rework for Miraak's soul steal in +;the apocrypha boss fight +DLC2SoulStealScript Property DLC2SoulSteal Auto +Actor Property DLC2MiraakMQ06Ref Auto +Location Property DLC2ApocryphaLocation Auto +Worldspace Property DLC2ApocryphaWorld Auto +ReferenceAlias Property DLC2MQ06MiraakAlias Auto +DLC2MQ06MiraakBossBattle Property DLC2BossBattleScript Auto hidden + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ALTERNATE VERSION OF THE DEATH SEQUENCE FOR MQ06 +; This absorbes the soul much faster +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +function MQ06DeathSequence(Actor dragonRef, Actor AbsorbActor = None, bool MiraakAppears = False) +;ADDED "Actor AbsorbActor = none, bool MiraakAppears = false" FOR DLC2 + + if dragonRef.IsInFaction(NoDragonAbsorb) + return + endif + + ; Add Skeleton to dragon's inventory. + dragonRef.AddItem(DragonUnderskin) + + ; Dragon wings particles bits + + FXDragonDeathLHandBits.Play(dragonRef, 12) + FXDragonDeathRHandBits.Play(dragonRef, 12) + + + ;wait(0.2) + + ;Equip skeleton under skin + dragonRef.EquipItem(DragonUnderskin) + ;wait(0.5) + dragonRef.PlaySubGraphAnimation("UnderSkinFadeOut") + +;************************************************************************** +; This is the bit that plays the absorb stuff, needed to move it up for Miraak + ;display dragon absorb effect art. One part on dragon one part on player. + DragonAbsorbEffect.Play(dragonRef, 8, AbsorbActor) ;***DLC2: CHANGED FROM GetPlayer() to AbsorbActor +;; dragonRef.placeAtME(MAGDragonPowerAbsorbExplosion) + DragonAbsorbManEffect.Play(AbsorbActor, 8, dragonRef) ;***DLC2: CHANGED FROM GetPlayer() to AbsorbActor + + ; Sounds for when the wispy particles being to fly at the player. + NPCDragonDeathSequenceWind.play(dragonRef) + NPCDragonDeathSequenceExplosion.play(dragonRef) + + DLC2BossBattleScript = DLC2MQ06MiraakAlias as DLC2MQ06MiraakBossBattle + DLC2BossBattleScript.MiraakStealsSoul() + DLC2SoulSteal.ModDLC2SoulStealCount(1) + ;wait(0.1) + + ; On man power absorb effect shader. + DragonPowerAbsorbFXS.Play(AbsorbActor) ;***DLC2: CHANGED FROM GetPlayer() to AbsorbActor + + ;wait(1) + ; turn off remaining effect bits and magic leak fxshaders + + + ;wait(1) + ; ghost the dragon so you can't hit him + dragonRef.SetGhost(true) + + ;clear any arrows that may have been stuck in dragon + dragonRef.clearExtraArrows() + + +;; + + ;wait(4) + + ;Stop fx shader on player showing power absorb. + DragonPowerAbsorbFXS.Stop(AbsorbActor) ;***DLC2: CHANGED FROM GetPlayer() to AbsorbActor + + +;************************************************************************** + ;*** CHANGED FOR DLC2-------------------------------------------------------- + + + + + + ;TryMiraakMakeHisIntroduction(DragonRef) + + ;------------------------------------------------------------------------------- + + ;*** WORLD INTERACTION FUNCTION -- jduvall + ;WI.PlayerIsCurrentlyAbsorbingPower(dragonRef) + bIsAbsorbing = true + + ; Start effect shader decorating holes in the base skin + DragonHolesFXS.Play(dragonRef) + ; Play disintegrating skin. + dragonRef.PlaySubGraphAnimation( "SkinFadeOut" ) +;;; + ; Play imagespace modifier which is timed to match sequence. + DragonPowerAbsorbISM.Apply() + + ; Sound of dragon carcass first bursts into flames until the flames die off. Must be turned off + int soundInstanceFireID = NPCDragonDeathSequenceFireLPM.play(dragonRef) + + wait(1) + + ;Small bits rising from dragon fx shader. + DragonHolesBitsLiteFXS.Play(dragonRef) + + wait(1) + ;Bigger bits rising from dragon fx shader. + DragonHolesBitsFXS.Play(dragonRef) + + wait(2) + + + + wait(1.75) + ;Play blood fade out if it is there + dragonRef.PlaySubGraphAnimation("BloodFade") + + ; Magic particles on wings + FXDragonDeathRHandFire.Play(dragonRef, 12) + FXDragonDeathLHandFire.Play(dragonRef, 12) + + wait(1.0) + ; magic fire fx shader + DragonHolesMagicFXS.Play(dragonRef) + DragonHolesMagicFXS.Stop(dragonRef);;;;;;;;;;;;;;;;;;;;;;;; + + wait(0.25) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;StopDragon bits fxs + DragonHolesBitsFXS.Stop(dragonRef) + DragonHolesBitsLiteFXS.Stop(dragonRef) + ;Stop holes fx shader now that main dragon skin is un-worn + DragonHolesFXS.Stop(dragonRef) + + ; Play light emitting magic shader on dragon +;; DragonHolesLightFXS.Play(dragonRef) + + wait(1.8) + ;unequipp invisible art + if dragonRef.IsEquipped(DragonBloodHeadFXArmor) == true + dragonRef.unEquipItem(DragonBloodHeadFXArmor) + endif + if dragonRef.IsEquipped(DragonBloodTailFXArmor) == true + dragonRef.unEquipItem(DragonBloodTailFXArmor) + endif + if dragonRef.IsEquipped(DragonBloodWingLFXArmor) == true + dragonRef.unEquipItem(DragonBloodWingLFXArmor) + endif + if dragonRef.IsEquipped(DragonBloodWingRFXArmor) == true + dragonRef.unEquipItem(DragonBloodWingRFXArmor) + endif + + ; End sound of dragon carcass bursting into flames. + StopInstance(soundInstanceFireID) +;*********************************************************************** + + ; add lingering smoke and glow to dragon carcass. + DragonHolesSmokeFXS.Play(dragonRef) + + ; Start sound for smoldering dragon + int soundInstanceSmolderID = NPCDragonDeathSequenceSmolderLPM.play(dragonRef) + + wait(4) + +;*** -------------------------------------------------------------------------- + + + ; turn off effect shaders for smoldering carcass + DragonHolesSmokeFXS.Stop(dragonRef) + + ; Get rid of art attached to dragon and player showing streaming magic. + DragonAbsorbEffect.Stop(dragonRef) + DragonAbsorbManEffect.Stop(AbsorbActor) ;***DLC2: CHANGED FROM GetPlayer() to AbsorbActor + + wait(4) + + ;Stop smoldering sound + StopInstance(soundInstanceSmolderID) + + ; put dragon in faction so other quests know player has absorbed power + dragonRef.addtoFaction(MQKillDragonFaction) + + ;Stop light emitting magic shader on dragon + DragonHolesLightFXS.Stop(dragonRef) + + ;*** WORLD INTERACTION FUNCTION -- jduvall + WI.PlayerIsDoneAbsorbingPower(dragonRef) + + dragonRef.EquipItem(SkinDragonHider, true) + + bIsAbsorbing = false + +endFunction + +;--------------------------------------------------------- \ No newline at end of file diff --git a/source/scripts/ms10questscript.psc b/source/scripts/ms10questscript.psc new file mode 100644 index 00000000..efe0ba89 --- /dev/null +++ b/source/scripts/ms10questscript.psc @@ -0,0 +1,64 @@ +Scriptname MS10QuestScript extends Quest Conditional + +Book Property Journal Auto +int Property RewardAmount Auto +MiscObject Property RewardItem Auto +bool Property FightingStig Auto +bool Property KnowsNameOfPirates Auto Conditional +bool Property StigIntroduced Auto Conditional +bool Property PlayerKnowsAboutHaldyn Auto Conditional +bool Property AdelaisaFGInOffice Auto Conditional +bool Property StigPersuaded Auto Conditional +int Property BribeAmount Auto +MiscObject Property BribeItem Auto + +ReferenceAlias Property Adelaisa auto +ReferenceAlias Property ShipInWindhelm auto +ReferenceAlias Property ShipDoorInWindhelm auto +ReferenceAlias Property Haldyn auto +ReferenceAlias Property ShipAtIsland auto +ObjectReference Property RemotePlayerTarget auto +ObjectReference Property RemoteAdelaisaTarget auto +ObjectReference Property LocalPlayerTarget auto +ObjectReference Property LocalAdelaisaTarget auto + +ReferenceAlias Property Follower auto ; on DialogueFollower +ReferenceAlias Property AnimalFollower auto ; on DialogueFollower +ObjectReference Property FollowerTarget auto +ObjectReference Property LocalFollowerTarget auto +ObjectReference Property AnimalFollowerTarget auto +ObjectReference Property LocalAnimalFollowerTarget auto + + +Function SetSail() + Haldyn.GetReference().Enable() + ShipAtIsland.GetReference().Enable() + Game.GetPlayer().MoveTo(RemotePlayerTarget) + ShipInWindhelm.GetReference().Disable() + ShipDoorInWindhelm.GetReference().Disable() + if (Follower.GetReference() != None) + Follower.GetReference().MoveTo(FollowerTarget) + endif + if (AnimalFollower.GetReference() != None) + AnimalFollower.GetReference().MoveTo(AnimalFollowerTarget) + endif + Adelaisa.GetReference().MoveTo(RemoteAdelaisaTarget) + SetStage(42) ;insert some joke about the meaning of life here +EndFunction + +Function HeadBackHome() + ShipInWindhelm.GetReference().Enable() + Game.GetPlayer().MoveTo(LocalPlayerTarget) + if (Follower.GetReference() != None) + Follower.GetReference().MoveTo(LocalFollowerTarget) + endif + if (AnimalFollower.GetReference() != None) + AnimalFollower.GetReference().MoveTo(LocalAnimalFollowerTarget) + endif + Adelaisa.GetReference().MoveTo(LocalAdelaisaTarget) + SetStage(80) +EndFunction + +Function GetErDoneWithStig() + StigPersuaded = True +EndFunction diff --git a/source/scripts/ms11questscript.psc b/source/scripts/ms11questscript.psc new file mode 100644 index 00000000..9b4b7155 --- /dev/null +++ b/source/scripts/ms11questscript.psc @@ -0,0 +1,163 @@ +Scriptname MS11QuestScript extends Quest Conditional + +bool Property QuestionedWitness1 Auto Conditional +bool Property QuestionedWitness2 Auto Conditional +bool Property QuestionedWitness3 Auto Conditional +bool Property PlayerHasAuthority Auto Conditional +bool Property PlayerHasFoundHorridRoom Auto Conditional +bool Property CalixtoDead Auto Conditional +bool Property SentViolaToHjerim Auto Conditional +bool Property GotRedHerringFromCalixto Auto Conditional +bool Property PlayerInStoneQuarter Auto Conditional +bool Property PlayerInMurderZone Auto Conditional ; best variable name ever? + +bool Property PlayerReadJournal2 auto conditional +bool Property GetInHjerimTovaPointer auto conditional +bool Property GetInHjerimUlfricPointer auto conditional +bool Property GetInHjerimHousePointer auto conditional +bool Property InvestigateViolaPointer auto conditional +bool Property InvestigateCalixtoPointer auto conditional +bool Property GuardGavePlayerStory auto conditional + +bool Property ViolaConversationShunt = false auto conditional +bool Property PlayerTalkedToViolaAboutButcher auto conditional + +bool Property SiegeOfWindhelmTakingPlace auto conditional + +ReferenceAlias Property Calixto auto +ReferenceAlias Property Arivanya auto +ReferenceAlias Property PotentialThirdVictim auto +ReferenceAlias Property FinalVictim auto + +; 77465: bad deletion of disabled corpse +ReferenceAlias Property InitialVictimBody auto +ActorBase Property AlternateBody auto +ReferenceAlias Property CrimeScene auto +Faction Property HarmlessCorpse auto +; /77465 + +Package Property VictimWanderPackage auto +Scene Property CalixtoKILLKILLKILLScene auto +Armor Property InnocuousAmulet auto +Armor Property NecromancersAmulet auto + +Quest Property ShadowQuest auto +ObjectReference Property HjerimDoor auto + +ReferenceAlias Property Helgird auto +ObjectReference Property OriginalBody auto +ObjectReference Property HallOfDeadBrowseMarker auto +bool Property BodyIsInHallOfDead auto conditional +bool Property TalkedToHelgird auto conditional + +bool Property WuunferthArrested auto conditional + +Perk Property Investigator auto + +Function Setup() + ; set up investigation stuff + Game.GetPlayer().AddPerk(Investigator) + + ; change Hjerim door from impossible to very hard + HjerimDoor.SetLockLevel(100) + +; Debug.Trace("MS11: Kicked off.") +EndFunction + +; 77465: bad deletion of disabled corpse +Function CheckForDeletedBody() +; Debug.Trace("MS11: Checking for presence of bug 77465.") + if (InitialVictimBody.GetReference() == None) +; Debug.Trace("MS11: 77465 detected; correcting.") + Actor alt = CrimeScene.GetReference().PlaceAtMe(AlternateBody) as Actor + alt.AddToFaction(HarmlessCorpse) + alt.Kill() + InitialVictimBody.ForceRefTo(alt) +; Debug.Trace("MS11: Crime scene is " + CrimeScene) +; Debug.Trace("MS11: Alt is " + alt) + endif +EndFunction +; /77465 + +Function DisableIfNotCompleted(int objective) + if (!IsObjectiveCompleted(objective)) + SetObjectiveDisplayed(objective, 0) + endif +EndFunction + +Function ResolveObjective(int complete, int display) + Quest targetQuest = None + if (ShadowQuest.IsRunning()) + ; we're running MS11b based on the quest "resuming" + targetQuest = ShadowQuest + else + ; player is good detective + targetQuest = self + endif + + if (complete != 0) +; Debug.Trace("MS11: Setting obj " + complete + " completed on " + targetQuest) + targetQuest.SetObjectiveCompleted(complete, true) + endif + if (display != 0) +; Debug.Trace("MS11: Setting obj " + display + " displayed on " + targetQuest) + targetQuest.SetObjectiveDisplayed(display, true) + endif +EndFunction + +Function MoveBody() + if (!BodyIsInHallOfDead) + ; move Susanna's body to the hall of the dead + BodyIsInHallOfDead = true + InitialVictimBody.GetReference().Disable() + HallOfDeadBrowseMarker.Enable() + Actor helgirdAct = Helgird.GetActorReference() + helgirdAct.MoveTo(HallOfDeadBrowseMarker) + helgirdAct.EvaluatePackage() + endif +EndFunction + +Function CleanupHallOfDead() + if (BodyIsInHallOfDead) + BodyIsInHallOfDead = false + HallOfDeadBrowseMarker.Disable() + Helgird.GetActorReference().EvaluatePackage() + endif +EndFunction + +Function SetupStakeout() + ; give him the real article + if (Calixto.GetActorReference().GetItemCount(InnocuousAmulet) > 0) + Calixto.GetActorReference().RemoveItem(InnocuousAmulet, 1) + Calixto.GetActorReference().AddItem(NecromancersAmulet, 1) + endif + + ; pick the poor victim + if (!Arivanya.GetActorReference().IsDead()) + FinalVictim.ForceRefTo(Arivanya.GetActorReference()) + else + FinalVictim.ForceRefTo(PotentialThirdVictim.GetActorReference()) + endif + + ; just start the scene -- anything more fancy just breaks :-( + CalixtoKILLKILLKILLScene.Start() + + ; start checking as to when to start the scene + ; RegisterForUpdate(10) +EndFunction + + +Function Teardown() + Game.GetPlayer().RemovePerk(Investigator) +EndFunction + +;stubbed in by jduvall +function CivilWarBattle(bool BattleActive) +{When called the Civil War siege script is starting or stopping in Windhelm. BattleActive = true means starting, = false means stopping.} + +; debug.trace("MS11QuestScript CivilWarBattle(" + BattleActive + ")") + + SiegeOfWindhelmTakingPlace = BattleActive + +EndFunction + diff --git a/source/scripts/nightingalesecdoorscript.psc b/source/scripts/nightingalesecdoorscript.psc new file mode 100644 index 00000000..596e31ce --- /dev/null +++ b/source/scripts/nightingalesecdoorscript.psc @@ -0,0 +1,22 @@ +scriptName NightingaleSecDoorScript extends ObjectReference Conditional + +import debug +import utility + +;**************************** + +Auto STATE pulledPosition + EVENT onActivate (objectReference triggerRef) + gotoState ("busy") + playAnimationandWait("Open","Opened") + endEVENT +endState + +;**************************** + +STATE busy + ; This is the state when I'm busy animating + EVENT onActivate (objectReference triggerRef) + ;do nothing + endEVENT +endSTATE diff --git a/source/scripts/noflightabilityscript.psc b/source/scripts/noflightabilityscript.psc new file mode 100644 index 00000000..bca9dd61 --- /dev/null +++ b/source/scripts/noflightabilityscript.psc @@ -0,0 +1,5 @@ +scriptName NoFlightAbilityScript extends activeMagicEffect + +Event OnEffectStart(Actor Target, Actor Caster) + caster.setAllowFlying(False) +EndEvent diff --git a/source/scripts/norlever01script.psc b/source/scripts/norlever01script.psc new file mode 100644 index 00000000..2b52d593 --- /dev/null +++ b/source/scripts/norlever01script.psc @@ -0,0 +1,51 @@ +scriptName NorLever01SCRIPT extends ObjectReference Conditional + +import debug +import utility + +bool property isInPullPosition = True Auto + +EVENT OnLoad() + SetDefaultState() +endEVENT + +Event OnReset() + SetDefaultState() +EndEvent + +;This has to be handled as a function, since OnLoad and OnReset can fire in either order, and we can't handle competing animation calls. +Function SetDefaultState() + if (isInPullPosition) + playAnimation("FullPull") + gotoState("pulledPosition") + Else + playAnimation("FullPush") + gotoState("pushedPosition") + EndIf +EndFunction + + +Auto STATE pulledPosition + EVENT onActivate (objectReference triggerRef) + gotoState ("busy") + isInPullPosition = False + playAnimationandWait("FullPush","FullPushedUp") + gotoState("pushedPosition") + endEVENT +endState + +STATE pushedPosition + EVENT onActivate (objectReference triggerRef) + gotoState ("busy") + isInPullPosition = True + playAnimationandWait("FullPull","FullPulledDown") + gotoState("pulledPosition") + endEVENT +endState + +STATE busy + ; This is the state when I'm busy animating + EVENT onActivate (objectReference triggerRef) + ;do nothing + endEVENT +endSTATE diff --git a/source/scripts/norportcullisscript.psc b/source/scripts/norportcullisscript.psc new file mode 100644 index 00000000..aa4b57d0 --- /dev/null +++ b/source/scripts/norportcullisscript.psc @@ -0,0 +1,98 @@ +scriptName NorPortcullisSCRIPT extends ObjectReference + +import debug +import utility + +bool isOpen = false ;Is the portcullis already open + + +bool property isOpening +{ +True if the door is currently in the process of opening +} + bool Function Get() + if ( (GetState() == "busy") && (!isOpen) ) + return true + else + return false + endif + endFunction +EndProperty + +bool property isClosing +{ +True if the door is currently in the process of opening +} + bool Function Get() + if ( (GetState() == "busy") && (isOpen) ) + return true + else + return false + endif + endFunction +EndProperty + +bool property isAlreadyOpen ;Set "isOpen" to same as property "isAlreadyOpen" +{ +True = Portcullis is already open +False = Portcullis is closed (default) +} + bool Function Get () + return isOpen + endFunction + + Function Set(bool value) + isOpen = value + endFunction +endProperty + +EVENT OnLoad() + SetDefaultState() +endEVENT + +Event OnReset() + SetDefaultState() +EndEvent + +;This has to be handled as a function, since OnLoad and OnReset can fire in either order, and we can't handle competing animation calls. +Function SetDefaultState() + if (isOpen == false) + playAnimation("close") ; Animate Closed + gotostate ("upPosition") ;Portcullis Start Closed + else + playAnimation("open") ;Portcullis Starts Opened + gotostate ("downPosition") + endif +EndFunction + + + +STATE upPosition ; This is the state I'm in when open and at rest + EVENT onActivate (objectReference triggerRef) + gotoState ("busy") + ;trace("Portcullis Opening") + playAnimationandWait("open","opening") ; Animate Open + ;trace("Portcullis Opened") + isOpen = true + gotoState("downPosition") + endEVENT +endState + +STATE downPosition ; This is the state I'm in when i'm closed and at rest + EVENT onActivate (objectReference triggerRef) + gotoState ("busy") + ;trace("Portcullis Closing") + playAnimationandWait("close","closing") ; Animate Closed + ;trace("Portcullis Closed") + isOpen = false + gotoState("upPosition") + endEVENT +endState + +STATE busy + ; This is the state when I'm busy animating + EVENT onActivate (objectReference triggerRef) + ;trace ("Portcullis Busy") + endEVENT +endSTATE + diff --git a/source/scripts/norpullbar01script.psc b/source/scripts/norpullbar01script.psc new file mode 100644 index 00000000..3473c1f0 --- /dev/null +++ b/source/scripts/norpullbar01script.psc @@ -0,0 +1,12 @@ +scriptName NorPullBar01SCRIPT extends ObjectReference + +import debug +import utility + +Auto STATE Waiting + EVENT onActivate (objectReference triggerRef) + self.BlockActivation(true) + playAnimationandWait("Pull","Reset") + self.BlockActivation(false) + endEVENT +endState \ No newline at end of file diff --git a/source/scripts/norrotatingdoorscript.psc b/source/scripts/norrotatingdoorscript.psc new file mode 100644 index 00000000..092446af --- /dev/null +++ b/source/scripts/norrotatingdoorscript.psc @@ -0,0 +1,59 @@ +Scriptname norRotatingDoorSCRIPT extends ObjectReference +{THIS SHOULD BE ON THE LEVER A customizeable script for the nordic rotating doors THIS SHOULD BE ON THE LEVER} + +import debug +import utility +import game +import sound + +; the door we're manipulating +OBJECTREFERENCE myDoor + +; does it start open +BOOL PROPERTY startOpen AUTO + +; //the start and stop sounds +SOUND PROPERTY startingSound AUTO +SOUND PROPERTY stoppingSound AUTO + +INT soundID + +; // ON INIT MAKE SURE WE'RE IN THE DEFAULT POSITION +EVENT onLoad() + + ; a linked reference to the door + myDoor = getLinkedREF() + + IF(!startOpen) + myDoor.playAnimation("SnapOpen") + ELSE + myDoor.playAnimation("SnapClosed") + ENDIF + +endEVENT + +AUTO STATE OFFpos + EVENT onActivate (objectReference triggerRef) + + ;soundID = startingSound.play(SELF) + + IF(!startOpen) + + myDoor.playAnimationandWait("RotateClosed", "snapClosed") + startOpen = TRUE + + ELSE + + myDoor.playAnimationandWait("RotateOpen", "snapOpen") + startOpen = FALSE + ENDIF + + ;stopInstance(soundID) + + ENDEVENT +ENDSTATE + + +STATE busyState + ; don't do anything while I'm busy. +ENDSTATE diff --git a/source/scripts/norsarcophagustopanim01script.psc b/source/scripts/norsarcophagustopanim01script.psc new file mode 100644 index 00000000..1610e25e --- /dev/null +++ b/source/scripts/norsarcophagustopanim01script.psc @@ -0,0 +1,44 @@ +scriptName NorSarcophagusTopAnim01SCRIPT extends ObjectReference +{This script causes the sarcophagus lid to animate when activated} + + +import debug +import utility + +;bool onLoadDone +;bool onResetDone +bool isOpened = false + +;******************************************* + +Event onReset() + onLoad() +endEvent + +;******************************************* + +Event onLoad() + if(!isOpened) + playAnimation("SnapClosed") + endif +endEvent + +;******************************************* + +Auto State waiting + Event onActivate (objectReference triggerRef) + gotoState ("busy") + isOpened = true + playAnimation("OpenStart") + endEvent +endState + +;******************************************* + +State busy + Event onActivate (objectReference triggerRef) + ;do nothing + endEvent +endState + +;******************************************* \ No newline at end of file diff --git a/source/scripts/pdbentrancequestscript.psc b/source/scripts/pdbentrancequestscript.psc new file mode 100644 index 00000000..80c3470b --- /dev/null +++ b/source/scripts/pdbentrancequestscript.psc @@ -0,0 +1,59 @@ +Scriptname pDBEntranceQuestScript extends Quest Conditional + +Quest Property WICourier Auto +Book Property DBEntranceLetter Auto +int Property pSleepyTime Auto Conditional +ObjectReference Property pPlayerShackMarker Auto +ReferenceAlias Property pAstridAlias Auto +int Property pPlayerSecondSleep Auto Conditional +Idle Property WakeUp Auto +ImageSpaceModifier Property Woozy Auto + +; When stage is set to 30, register for sleep via RegisterForSleep() + +Event OnSleepStart(float afSleepStartTime, float afDesiredSleepEndTime) + +; For the player sleeping, to move him to the shack to be forcegreeted by Astrid. +If pSleepyTime == 1 + Game.DisablePlayerControls(ablooking = true, abCamSwitch = true) + Game.ForceFirstPerson() + Game.GetPlayer().MoveTo(pPlayerShackMarker) + Woozy.Apply() + Game.GetPlayer().PlayIdle(WakeUp) + Utility.Wait (3) + pSleepyTime = 3 +endif + +;Tempted in for future, when sleeping is working +;If the player is sleeping + ;play the sleeping/wake up animation + ;in previous block, set pSleepyTime to 2, and use 2 in this block to have the player play the wakeup animnation, then set to 3 to have Astrid forcegreet +;endif + +; For the player sleeping the second time, and being greeted by Astrid (commented out because it's no longer used) + +;If pPlayerSecondSleep == 0 + ;If pSleepyTime >= 5 + ;pSleepyTime = 6 + ;pAstridAlias.GetReference().Moveto (Game.GetPlayer(), afXOffset = 60.0) + ;pPlayerSecondSleep = 1 + ;endif +;endif + + +EndEvent + + + + +DarkBrotherhood Property DarkBrotherhoodQuest Auto + +ReferenceAlias Property Captive1Alias Auto + +ReferenceAlias Property Captive2Alias Auto + +ReferenceAlias Property Captive3Alias Auto + +int Property AstridSleepGreet Auto Conditional + +int Property AstridMove Auto Conditional diff --git a/source/scripts/pf_ambushsleeplinkedref_00048abc.psc b/source/scripts/pf_ambushsleeplinkedref_00048abc.psc new file mode 100644 index 00000000..65905a15 --- /dev/null +++ b/source/scripts/pf_ambushsleeplinkedref_00048abc.psc @@ -0,0 +1,21 @@ +;BEGIN FRAGMENT CODE - Do not edit anything between this and the end comment +;NEXT FRAGMENT INDEX 3 +Scriptname PF_ambushSleepLinkedRef_00048ABC Extends Package Hidden + +;BEGIN FRAGMENT Fragment_2 +Function Fragment_2(Actor akActor) +;BEGIN CODE +akActor.setAV("Aggression", 2) +;END CODE +EndFunction +;END FRAGMENT + +;BEGIN FRAGMENT Fragment_5 +Function Fragment_5(Actor akActor) +;BEGIN CODE +akActor.setAV("Aggression", 2) +;END CODE +EndFunction +;END FRAGMENT + +;END FRAGMENT CODE - Do not edit anything between this and the begin comment diff --git a/source/scripts/pf_carryfirewood_000d97fa.psc b/source/scripts/pf_carryfirewood_000d97fa.psc new file mode 100644 index 00000000..d64bff40 --- /dev/null +++ b/source/scripts/pf_carryfirewood_000d97fa.psc @@ -0,0 +1,37 @@ +;BEGIN FRAGMENT CODE - Do not edit anything between this and the end comment +;NEXT FRAGMENT INDEX 4 +Scriptname PF_CarryFirewood_000D97FA Extends Package Hidden + +;BEGIN FRAGMENT Fragment_2 +Function Fragment_2(Actor akActor) +;BEGIN CODE +; ; debug.trace(self + " OnEnd") +;ObjectReference meRef = akActor as ObjectReference +;(meRef as CarryActorScript).ChangeCarryState(false) +;END CODE +EndFunction +;END FRAGMENT + +;BEGIN FRAGMENT Fragment_1 +Function Fragment_1(Actor akActor) +;BEGIN CODE +; ; debug.trace(self + " OnChange") +ObjectReference meRef = akActor as ObjectReference +(meRef as CarryActorScript).ChangeCarryState(false) +;END CODE +EndFunction +;END FRAGMENT + +;BEGIN FRAGMENT Fragment_3 +Function Fragment_3(Actor akActor) +;BEGIN CODE +; ; debug.trace(self + " OnBegin") +ObjectReference meRef = akActor as ObjectReference +(meRef as CarryActorScript).ChangeCarryState(true) +;END CODE +EndFunction +;END FRAGMENT + +;END FRAGMENT CODE - Do not edit anything between this and the begin comment + +MiscObject Property CarryItem Auto diff --git a/source/scripts/pf_dgintimidatespectatorpacka_000aa053.psc b/source/scripts/pf_dgintimidatespectatorpacka_000aa053.psc new file mode 100644 index 00000000..3993e110 --- /dev/null +++ b/source/scripts/pf_dgintimidatespectatorpacka_000aa053.psc @@ -0,0 +1,21 @@ +;BEGIN FRAGMENT CODE - Do not edit anything between this and the end comment +;NEXT FRAGMENT INDEX 2 +Scriptname PF_DGIntimidateSpectatorPacka_000AA053 Extends Package Hidden + +;BEGIN FRAGMENT Fragment_1 +Function Fragment_1(Actor akActor) +;BEGIN CODE +akactor.SetLookAt(Game.GetPlayer(), true) +;END CODE +EndFunction +;END FRAGMENT + +;BEGIN FRAGMENT Fragment_0 +Function Fragment_0(Actor akActor) +;BEGIN CODE +akactor.ClearLookAt() +;END CODE +EndFunction +;END FRAGMENT + +;END FRAGMENT CODE - Do not edit anything between this and the begin comment diff --git a/source/scripts/pf_dgintimidatespectatorpacka_000aa054.psc b/source/scripts/pf_dgintimidatespectatorpacka_000aa054.psc new file mode 100644 index 00000000..abee54f6 --- /dev/null +++ b/source/scripts/pf_dgintimidatespectatorpacka_000aa054.psc @@ -0,0 +1,21 @@ +;BEGIN FRAGMENT CODE - Do not edit anything between this and the end comment +;NEXT FRAGMENT INDEX 2 +Scriptname PF_DGIntimidateSpectatorPacka_000AA054 Extends Package Hidden + +;BEGIN FRAGMENT Fragment_1 +Function Fragment_1(Actor akActor) +;BEGIN CODE +akactor.ClearLookAt() +;END CODE +EndFunction +;END FRAGMENT + +;BEGIN FRAGMENT Fragment_0 +Function Fragment_0(Actor akActor) +;BEGIN CODE +akactor.SetLookAt(Game.GetPlayer(), true) +;END CODE +EndFunction +;END FRAGMENT + +;END FRAGMENT CODE - Do not edit anything between this and the begin comment diff --git a/source/scripts/physicstraphit.psc b/source/scripts/physicstraphit.psc new file mode 100644 index 00000000..f051b924 --- /dev/null +++ b/source/scripts/physicstraphit.psc @@ -0,0 +1,83 @@ +scriptName PhysicsTrapHit extends TrapHitBase +; +; +; +;========================================= + +import utility + +float property damageVelocityThreshold = 6.0 auto +{This sets the velocity needed to apply damage + It is non-squareroot of the delta velocity as recieved from the TrapHit + Default = 6.0 + This should NOT be changed on the Ref except in rare cases} + +Auto state CanHit + Event OnTrapHitStart(ObjectReference akTarget, float afXVel, float afYVel, float afZVel, float afXPos, float afYPos, float afZPos, int aeMaterial, bool abInitialHit, int aeMotionType) + ;goToState("CannotHit") + + if acceptableVelocityDelta(damageVelocityThreshold, afXVel, afYVel, afZVel) +; debug.Trace(self + " is dealing damage!!!") + ;damage = 40 ;THIS IS FOR A TEST ONLY + if !(akTarget as actor).hasSpell(ghostAbility) && !(akTarget as actor).IsInFaction(noHitFaction) + if hitOnlyOnce + goToState("CannotHit") + endif + if akTarget == game.GetPlayer() + if rumble + game.ShakeController(rumbleAmount, rumbleAmount, rumbleDuration) + EndIf + if cameraShake + game.ShakeCamera(afStrength = cameraShakeAmount) + endif + endif + akTarget.ProcessTrapHit(self, damage, trapPushBack, afXVel, afYVel, afZVel, afXPos, afYPos, afZPos, aeMaterial, staggerAmount) + if TrapHitSound + TrapHitSound.play( self as ObjectReference) ;play hit sound + endif + ;hitFX.fire(self, hitFxAmmo) + CreateDetectionEvent(akTarget as actor, soundLevel) ; creates a detection event + endif + endif + + endEvent +endState + +state CannotHit + Event OnTrapHit(ObjectReference akTarget, float afXVel, float afYVel, float afZVel, float afXPos, float afYPos, float afZPos, int aeMaterial, bool abInitialHit, int aeMotionType) + endEvent +endState + + +bool function acceptableVelocityDelta(float targetVelocity, float afXVel, float afYVel, float afZVel) + float actualDeltaVelocity + float xyDelta + + ;xyDelta = math.sqrt(math.pow(afXVel, 2) + math.pow(afYVel, 2)) + + ;actualDeltaVelocity = math.sqrt(math.pow(xyDelta, 2) + math.pow(afZVel, 2)) + + ;actualDeltaVelocity = (math.abs(afxVel) + math.abs(afYVel) + math.abs(afZVel)) + actualDeltaVelocity = ((afxVel * afxVel) + (afyVel * afyVel) + (afZVel * afZVel)) + + if actualDeltaVelocity >= targetVelocity +; debug.trace(self + " actualVelocity >= targetVelocity") +; debug.trace(self + " deltaX = " + afXVel) +; debug.trace(self + " deltaY = " + afYVel) +; debug.trace(self + " deltaZ = " + afZVel) +; debug.trace(self + " targetVelocity = " + targetVelocity) +; debug.trace(self + " totalDelta = " + actualDeltaVelocity) + return True + Else +; debug.trace(self + " actualVelocity < targetVelocity") +; debug.trace(self + " deltaX = " + afXVel) +; debug.trace(self + " deltaY = " + afYVel) +; debug.trace(self + " deltaZ = " + afZVel) +; debug.trace(self + " targetVelocity = " + targetVelocity) +; debug.trace(self + " totalDelta = " + actualDeltaVelocity) + return False + endif + + +endFunction + \ No newline at end of file diff --git a/source/scripts/playerbookshelfclicktriggerscript.psc b/source/scripts/playerbookshelfclicktriggerscript.psc new file mode 100644 index 00000000..90ab7ee9 --- /dev/null +++ b/source/scripts/playerbookshelfclicktriggerscript.psc @@ -0,0 +1,26 @@ +Scriptname PlayerBookShelfClickTriggerSCRIPT extends ObjectReference + +import debug +import utility + +ObjectReference Property ShelfContainer auto hidden + +Keyword Property BookShelfContainer Auto + +Bool Property AlreadyLoaded = FALSE Auto Hidden + + +EVENT OnCellLoad() + if AlreadyLoaded == FALSE + ShelfContainer = GetLinkedRef(BookShelfContainer) + AlreadyLoaded = TRUE + endif +endEVENT + + +EVENT OnActivate(ObjectReference TriggerRef) + + Trace("DARYL - " + self + " I've been activated, opening container: " + ShelfContainer) + ShelfContainer.Activate(Game.GetPlayer(), FALSE) + +endEVENT diff --git a/source/scripts/playerbookshelfcontainerscript.psc b/source/scripts/playerbookshelfcontainerscript.psc new file mode 100644 index 00000000..f93dc73d --- /dev/null +++ b/source/scripts/playerbookshelfcontainerscript.psc @@ -0,0 +1,621 @@ +Scriptname PlayerBookShelfContainerScript extends ObjectReference + +import debug +import utility + +Form Property LItemBookClutter Auto +{Clutter item list to fill the shelf with} + +Keyword Property BookShelfBook01 Auto +Keyword Property BookShelfBook02 Auto +Keyword Property BookShelfBook03 Auto +Keyword Property BookShelfBook04 Auto +Keyword Property BookShelfBook05 Auto +Keyword Property BookShelfBook06 Auto +Keyword Property BookShelfBook07 Auto +Keyword Property BookShelfBook08 Auto +Keyword Property BookShelfBook09 Auto +Keyword Property BookShelfBook10 Auto +Keyword Property BookShelfBook11 Auto +Keyword Property BookShelfBook12 Auto +Keyword Property BookShelfBook13 Auto +Keyword Property BookShelfBook14 Auto +Keyword Property BookShelfBook15 Auto +Keyword Property BookShelfBook16 Auto +Keyword Property BookShelfBook17 Auto +Keyword Property BookShelfBook18 Auto +Keyword Property BookShelfTrigger01 Auto +Keyword Property BookShelfTrigger02 Auto +Keyword Property BookShelfTrigger03 Auto +Keyword Property BookShelfTrigger04 Auto +{List of required Keywords} + +ObjectReference Property BookMarker01 Auto Hidden +ObjectReference Property BookMarker02 Auto Hidden +ObjectReference Property BookMarker03 Auto Hidden +ObjectReference Property BookMarker04 Auto Hidden +ObjectReference Property BookMarker05 Auto Hidden +ObjectReference Property BookMarker06 Auto Hidden +ObjectReference Property BookMarker07 Auto Hidden +ObjectReference Property BookMarker08 Auto Hidden +ObjectReference Property BookMarker09 Auto Hidden +ObjectReference Property BookMarker10 Auto Hidden +ObjectReference Property BookMarker11 Auto Hidden +ObjectReference Property BookMarker12 Auto Hidden +ObjectReference Property BookMarker13 Auto Hidden +ObjectReference Property BookMarker14 Auto Hidden +ObjectReference Property BookMarker15 Auto Hidden +ObjectReference Property BookMarker16 Auto Hidden +ObjectReference Property BookMarker17 Auto Hidden +ObjectReference Property BookMarker18 Auto Hidden +ObjectReference Property BookShelfTrigger01Ref Auto Hidden +ObjectReference Property BookShelfTrigger02Ref Auto Hidden +ObjectReference Property BookShelfTrigger03Ref Auto Hidden +ObjectReference Property BookShelfTrigger04Ref Auto Hidden + +Int Property MaxBooksAllowed Auto Hidden +{Max books allowed on this partciular shelf} + +Int Property CurrentBookAmount Auto Hidden +{The current amount of books placed on the shelf} + +Form Property EmptyForm Auto Hidden +{Null Form} + +ObjectReference Property EmptyRef Auto Hidden +{Null Ref} + +Form Property CurrentBookForm Auto Hidden +{Book Form we are working with at any one time} + +ObjectReference Property CurrentBookRef Auto Hidden +{Book Ref we are working with at any one time} + +Form Property PlacedBook01 Auto Hidden +Form Property PlacedBook02 Auto Hidden +Form Property PlacedBook03 Auto Hidden +Form Property PlacedBook04 Auto Hidden +Form Property PlacedBook05 Auto Hidden +Form Property PlacedBook06 Auto Hidden +Form Property PlacedBook07 Auto Hidden +Form Property PlacedBook08 Auto Hidden +Form Property PlacedBook09 Auto Hidden +Form Property PlacedBook10 Auto Hidden +Form Property PlacedBook11 Auto Hidden +Form Property PlacedBook12 Auto Hidden +Form Property PlacedBook13 Auto Hidden +Form Property PlacedBook14 Auto Hidden +Form Property PlacedBook15 Auto Hidden +Form Property PlacedBook17 Auto Hidden +Form Property PlacedBook16 Auto Hidden +Form Property PlacedBook18 Auto Hidden +{List of Placed Book Forms} + +ObjectReference Property PlacedBook01Ref Auto Hidden +ObjectReference Property PlacedBook02Ref Auto Hidden +ObjectReference Property PlacedBook03Ref Auto Hidden +ObjectReference Property PlacedBook04Ref Auto Hidden +ObjectReference Property PlacedBook05Ref Auto Hidden +ObjectReference Property PlacedBook06Ref Auto Hidden +ObjectReference Property PlacedBook07Ref Auto Hidden +ObjectReference Property PlacedBook08Ref Auto Hidden +ObjectReference Property PlacedBook09Ref Auto Hidden +ObjectReference Property PlacedBook10Ref Auto Hidden +ObjectReference Property PlacedBook11Ref Auto Hidden +ObjectReference Property PlacedBook12Ref Auto Hidden +ObjectReference Property PlacedBook13Ref Auto Hidden +ObjectReference Property PlacedBook14Ref Auto Hidden +ObjectReference Property PlacedBook15Ref Auto Hidden +ObjectReference Property PlacedBook17Ref Auto Hidden +ObjectReference Property PlacedBook16Ref Auto Hidden +ObjectReference Property PlacedBook18Ref Auto Hidden +{List of Placed Book Refs} + +Bool Property AlreadyLoaded = FALSE Auto Hidden +{Whether this scritp has already went through it's OnCellLoad() Event} + +Bool Property BlockBooks = FALSE Auto Hidden +{Used for when you can't place any more books} + +Message Property BookShelfFirstActivateMESSAGE Auto +{Display message when the player activates a bookshelf for the first time. Only displays once.} + +Message Property BookShelfNoMoreRoomMESSAGE Auto +{Displayed message for when the amount of books the player is placing excedes the shelf limit.} + +Message Property BookShelfNotABookMESSAGE Auto +{Message displayed when the player places a non book form in the container.} + +Message Property BookShelfRoomLeftMESSAGE Auto +{Notification that tells the player how much room is left on the shelf upon first activating it.} + +GlobalVariable Property BookShelfGlobal Auto +{Global showing whether or not the player has ever activated a bookshelf} + + +EVENT OnCellLoad() + if AlreadyLoaded == FALSE + ;Trace("BOOKCASE - Running OnCellLoad()") + ; Get all the book markers + BookMarker01 = GetLinkedRef(BookShelfBook01) + BookMarker02 = GetLinkedRef(BookShelfBook02) + BookMarker03 = GetLinkedRef(BookShelfBook03) + BookMarker04 = GetLinkedRef(BookShelfBook04) + BookMarker05 = GetLinkedRef(BookShelfBook05) + BookMarker06 = GetLinkedRef(BookShelfBook06) + BookMarker07 = GetLinkedRef(BookShelfBook07) + BookMarker08 = GetLinkedRef(BookShelfBook08) + BookMarker09 = GetLinkedRef(BookShelfBook09) + BookMarker10 = GetLinkedRef(BookShelfBook10) + BookMarker11 = GetLinkedRef(BookShelfBook11) + BookMarker12 = GetLinkedRef(BookShelfBook12) + BookMarker13 = GetLinkedRef(BookShelfBook13) + BookMarker14 = GetLinkedRef(BookShelfBook14) + BookMarker15 = GetLinkedRef(BookShelfBook15) + BookMarker16 = GetLinkedRef(BookShelfBook16) + BookMarker17 = GetLinkedRef(BookShelfBook17) + BookMarker18 = GetLinkedRef(BookShelfBook18) + BookShelfTrigger01Ref = (GetLinkedRef(BookShelfTrigger01) as PlayerBookShelfTriggerSCRIPT) + BookShelfTrigger02Ref = (GetLinkedRef(BookShelfTrigger02) as PlayerBookShelfTriggerSCRIPT) + BookShelfTrigger03Ref = (GetLinkedRef(BookShelfTrigger03) as PlayerBookShelfTriggerSCRIPT) + BookShelfTrigger04Ref = (GetLinkedRef(BookShelfTrigger04) as PlayerBookShelfTriggerSCRIPT) + ; Count how many books can be placed on this shelf + CountMaxBooks() + + AlreadyLoaded = TRUE + endif +endEVENT + + + +EVENT OnActivate(ObjectReference akActionRef) + ; Removing all items from container as a precaution + ;Trace("BOOKCASE - I've been ACTIVATED!") + BlockActivate() + ;Trace("BOOKCASE - Blocking activate on all books") + ;Trace("BOOKCASE - BookShelfTrigger01Ref = " + BookShelfTrigger01Ref) + BookShelfRoomLeftMESSAGE.Show((MaxBooksAllowed - CurrentBookAmount)) + ;debug.Notification("You can place " + (MaxBooksAllowed - CurrentBookAmount) + " more books on this shelf.") + + if (BookShelfGlobal.GetValue() == 0) + BookShelfFirstActivateMESSAGE.Show() + BookShelfGlobal.SetValue(1) + endif + ;CurrentBookAmount = 0 + + if BookShelfTrigger01Ref + ;Trace("BOOKCASE - Setting FIRST trigger to GoToState IgnoreBooks") + BookShelfTrigger01Ref.GoToState("IgnoreBooks") + endif + if BookShelfTrigger02Ref + ;Trace("BOOKCASE - Setting SECOND trigger to GoToState IgnoreBooks") + BookShelfTrigger02Ref.GoToState("IgnoreBooks") + endif + if BookShelfTrigger03Ref + ;Trace("BOOKCASE - Setting THIRD trigger to GoToState IgnoreBooks") + BookShelfTrigger03Ref.GoToState("IgnoreBooks") + endif + if BookShelfTrigger04Ref + ;Trace("BOOKCASE - Setting FOURTH trigger to GoToState IgnoreBooks") + BookShelfTrigger04Ref.GoToState("IgnoreBooks") + endif + + Wait(0.25) + ; The following will fire when the player leaves inventory + ;Trace("BOOKCASE - Out of Inventory so placing all the books") + UpdateBooks() + + if BookShelfTrigger01Ref + ;Trace("BOOKCASE - Setting FIRST trigger to GoToState WaitForBooks") + BookShelfTrigger01Ref.GoToState("WaitForBooks") + endif + if BookShelfTrigger02Ref + ;Trace("BOOKCASE - Setting SECOND trigger to GoToState WaitForBooks") + BookShelfTrigger02Ref.GoToState("WaitForBooks") + endif + if BookShelfTrigger03Ref + ;Trace("BOOKCASE - Setting THIRD trigger to GoToState WaitForBooks") + BookShelfTrigger03Ref.GoToState("WaitForBooks") + endif + if BookShelfTrigger04Ref + ;Trace("BOOKCASE - Setting FOURTH trigger to GoToState WaitForBooks") + BookShelfTrigger04Ref.GoToState("WaitForBooks") + endif +endEVENT + + +Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) + if (akBaseItem as Book) + if BlockBooks == FALSE + ; If the item is a book find the corresponding book reference and remove it. + ;Trace("BOOKCASE - Form being Removed " + akBaseItem + " is a Book! Remove it from the list") + RemoveBooks(akBaseItem, aiItemCount) + CurrentBookAmount = CurrentBookAmount - aiItemCount + else + BlockBooks = FALSE + endif + endif +endEvent + + +Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) + ;Trace("BOOKCASE - Adding " + akBaseItem + " to the Book Container") + + if (akBaseItem as Book) + ; If the item being added is a book then check to see if there is room in on the shelf. + ;Trace("BOOKCASE - Form being Added " + akBaseItem + " is a Book!") + if ((aiItemCount + CurrentBookAmount) <= MaxBooksAllowed) + ; There's room on teh shelf, manage the book placement + ;Trace("BOOKCASE - " + CurrentBookAmount + "/" + MaxBooksAllowed + " There is room for another book, lets place it on the shelf.") + AddBooks(akBaseItem, aiItemCount) + CurrentBookAmount = CurrentBookAmount + aiItemCount + else + ; There is no room on the shelf. Tell the player this and give him his book back. + ;Trace("BOOKCASE - " + CurrentBookAmount + "/" + MaxBooksAllowed + " There's no more room for books on this shelf.") + utility.waitMenuMode(0) + ;MessageBox("You can't place that many books on this shelf") + BookShelfNoMoreRoomMESSAGE.Show() + ;Trace("BOOKCASE - Remove it from this container...") + BlockBooks = TRUE + self.RemoveItem(akBaseItem, aiItemCount, true, Game.GetPlayer()) + ;Trace("BOOKCASE - ...and give it back to the player") + endif + else + ; The item placed in the container isn't a book, so give the player back and tell him only books are allowed. + ;Trace("BOOKCASE - Form " + akBaseItem + " is NOT a Book!") + ;Trace("BOOKCASE - Since the placed item wasn't a book remove it from the container...") + + self.RemoveItem(akBaseItem, aiItemCount, true, Game.GetPlayer()) + ;Trace("BOOKCASE - ...and give it back to the player") + + ;(Game.GetPlayer()).AddItem(akBaseItem, aiItemCount, True) + utility.WaitMenuMode(0) + ;MessageBox("You can only place books on this shelf") + BookShelfNotABookMESSAGE.Show() + endif + +endEvent + +Function BlockActivate() + if Placedbook01Ref + PlacedBook01Ref.BlockActivation(TRUE) + endif + if Placedbook02Ref + PlacedBook02Ref.BlockActivation(TRUE) + endif + if Placedbook03Ref + PlacedBook03Ref.BlockActivation(TRUE) + endif + if Placedbook04Ref + PlacedBook04Ref.BlockActivation(TRUE) + endif + if Placedbook05Ref + PlacedBook05Ref.BlockActivation(TRUE) + endif + if Placedbook06Ref + PlacedBook06Ref.BlockActivation(TRUE) + endif + if Placedbook07Ref + PlacedBook07Ref.BlockActivation(TRUE) + endif + if Placedbook08Ref + PlacedBook08Ref.BlockActivation(TRUE) + endif + if Placedbook09Ref + PlacedBook09Ref.BlockActivation(TRUE) + endif + if Placedbook10Ref + PlacedBook10Ref.BlockActivation(TRUE) + endif + if Placedbook11Ref + PlacedBook11Ref.BlockActivation(TRUE) + endif + if Placedbook12Ref + PlacedBook12Ref.BlockActivation(TRUE) + endif + if Placedbook13Ref + PlacedBook13Ref.BlockActivation(TRUE) + endif + if Placedbook14Ref + PlacedBook14Ref.BlockActivation(TRUE) + endif + if Placedbook15Ref + PlacedBook15Ref.BlockActivation(TRUE) + endif + if Placedbook16Ref + PlacedBook16Ref.BlockActivation(TRUE) + endif + if Placedbook17Ref + PlacedBook17Ref.BlockActivation(TRUE) + endif + if Placedbook18Ref + PlacedBook18Ref.BlockActivation(TRUE) + endif + ;Trace("BOOKCASE - All book activation has been blocked") +endFunction + +Function UnBlockActivate() + if Placedbook01Ref + PlacedBook01Ref.BlockActivation(FALSE) + endif + if Placedbook02Ref + PlacedBook02Ref.BlockActivation(FALSE) + endif + if Placedbook03Ref + PlacedBook03Ref.BlockActivation(FALSE) + endif + if Placedbook04Ref + PlacedBook04Ref.BlockActivation(FALSE) + endif + if Placedbook05Ref + PlacedBook05Ref.BlockActivation(FALSE) + endif + if Placedbook06Ref + PlacedBook06Ref.BlockActivation(FALSE) + endif + if Placedbook07Ref + PlacedBook07Ref.BlockActivation(FALSE) + endif + if Placedbook08Ref + PlacedBook08Ref.BlockActivation(FALSE) + endif + if Placedbook09Ref + PlacedBook09Ref.BlockActivation(FALSE) + endif + if Placedbook10Ref + PlacedBook10Ref.BlockActivation(FALSE) + endif + if Placedbook11Ref + PlacedBook11Ref.BlockActivation(FALSE) + endif + if Placedbook12Ref + PlacedBook12Ref.BlockActivation(FALSE) + endif + if Placedbook13Ref + PlacedBook13Ref.BlockActivation(FALSE) + endif + if Placedbook14Ref + PlacedBook14Ref.BlockActivation(FALSE) + endif + if Placedbook15Ref + PlacedBook15Ref.BlockActivation(FALSE) + endif + if Placedbook16Ref + PlacedBook16Ref.BlockActivation(FALSE) + endif + if Placedbook17Ref + PlacedBook17Ref.BlockActivation(FALSE) + endif + if Placedbook18Ref + PlacedBook18Ref.BlockActivation(FALSE) + endif + ;Trace("BOOKCASE - All book activation has been UNblocked") +endFunction + + +Function RemoveBooks(Form BookBase, Int BookAmount) + ; Find an empty book form and place the new book there + While BookAmount > 0 + if PlacedBook01 == BookBase + ;Trace("BOOKCASE - PlacedBook01 matches, Removing this book") + PlacedBook01 = EmptyForm + elseif PlacedBook02 == BookBase + ;Trace("BOOKCASE - PlacedBook02 matches, Removing this book") + PlacedBook02 = EmptyForm + elseif PlacedBook03 == BookBase + ;Trace("BOOKCASE - PlacedBook03 matches, Removing this book") + PlacedBook03 = EmptyForm + elseif PlacedBook04 == BookBase + ;Trace("BOOKCASE - PlacedBook04 matches, Removing this book") + PlacedBook04 = EmptyForm + elseif PlacedBook05 == BookBase + ;Trace("BOOKCASE - PlacedBook05 matches, Removing this book") + PlacedBook05 = EmptyForm + elseif PlacedBook06 == BookBase + ;Trace("BOOKCASE - PlacedBook06 matches, Removing this book") + PlacedBook06 = EmptyForm + elseif PlacedBook07 == BookBase + ;Trace("BOOKCASE - PlacedBook07 matches, Removing this book") + PlacedBook07 = EmptyForm + elseif PlacedBook08 == BookBase + ;Trace("BOOKCASE - PlacedBook08 matches, Removing this book") + PlacedBook08 = EmptyForm + elseif PlacedBook09 == BookBase + ;Trace("BOOKCASE - PlacedBook09 matches, Removing this book") + PlacedBook09 = EmptyForm + elseif PlacedBook10 == BookBase + ;Trace("BOOKCASE - PlacedBook10 matches, Removing this book") + PlacedBook10 = EmptyForm + elseif PlacedBook11 == BookBase + ;Trace("BOOKCASE - PlacedBook11 matches, Removing this book") + PlacedBook11 = EmptyForm + elseif PlacedBook12 == BookBase + ;Trace("BOOKCASE - PlacedBook12 matches, Removing this book") + PlacedBook12 = EmptyForm + elseif PlacedBook13 == BookBase + ;Trace("BOOKCASE - PlacedBook13 matches, Removing this book") + PlacedBook13 = EmptyForm + elseif PlacedBook14 == BookBase + ;Trace("BOOKCASE - PlacedBook14 matches, Removing this book") + PlacedBook14 = EmptyForm + elseif PlacedBook15 == BookBase + ;Trace("BOOKCASE - PlacedBook15 matches, Removing this book") + PlacedBook15 = EmptyForm + elseif PlacedBook16 == BookBase + ;Trace("BOOKCASE - PlacedBook16 matches, Removing this book") + PlacedBook16 = EmptyForm + elseif PlacedBook17 == BookBase + ;Trace("BOOKCASE - PlacedBook17 matches, Removing this book") + PlacedBook17 = EmptyForm + elseif PlacedBook18 == BookBase + ;Trace("BOOKCASE - PlacedBook18 matches, Removing this book") + PlacedBook18 = EmptyForm + endif + + BookAmount = BookAmount - 1 + + endWhile +endFunction + +Function AddBooks(Form BookBase, Int BookAmount) + ; Find an empty book form and place the new book there + While BookAmount > 0 + if PlacedBook01 == EmptyForm + ;Trace("BOOKCASE - PlacedBook01 is empty, placing book there") + PlacedBook01 = BookBase + elseif PlacedBook02 == EmptyForm + ;Trace("BOOKCASE - PlacedBook02 is empty, placing book there") + PlacedBook02 = BookBase + elseif PlacedBook03 == EmptyForm + ;Trace("BOOKCASE - PlacedBook03 is empty, placing book there") + PlacedBook03 = BookBase + elseif PlacedBook04 == EmptyForm + ;Trace("BOOKCASE - PlacedBook04 is empty, placing book there") + PlacedBook04 = BookBase + elseif PlacedBook05 == EmptyForm + ;Trace("BOOKCASE - PlacedBook05 is empty, placing book there") + PlacedBook05 = BookBase + elseif PlacedBook06 == EmptyForm + ;Trace("BOOKCASE - PlacedBook06 is empty, placing book there") + PlacedBook06 = BookBase + elseif PlacedBook07 == EmptyForm + ;Trace("BOOKCASE - PlacedBook07 is empty, placing book there") + PlacedBook07 = BookBase + elseif PlacedBook08 == EmptyForm + ;Trace("BOOKCASE - PlacedBook08 is empty, placing book there") + PlacedBook08 = BookBase + elseif PlacedBook09 == EmptyForm + ;Trace("BOOKCASE - PlacedBook09 is empty, placing book there") + PlacedBook09 = BookBase + elseif PlacedBook10 == EmptyForm + ;Trace("BOOKCASE - PlacedBook10 is empty, placing book there") + PlacedBook10 = BookBase + elseif PlacedBook11 == EmptyForm + ;Trace("BOOKCASE - PlacedBook11 is empty, placing book there") + PlacedBook11 = BookBase + elseif PlacedBook12 == EmptyForm + ;Trace("BOOKCASE - PlacedBook12 is empty, placing book there") + PlacedBook12 = BookBase + elseif PlacedBook13 == EmptyForm + ;Trace("BOOKCASE - PlacedBook13 is empty, placing book there") + PlacedBook13 = BookBase + elseif PlacedBook14 == EmptyForm + ;Trace("BOOKCASE - PlacedBook14 is empty, placing book there") + PlacedBook14 = BookBase + elseif PlacedBook15 == EmptyForm + ;Trace("BOOKCASE - PlacedBook15 is empty, placing book there") + PlacedBook15 = BookBase + elseif PlacedBook16 == EmptyForm + ;Trace("BOOKCASE - PlacedBook16 is empty, placing book there") + PlacedBook16 = BookBase + elseif PlacedBook17 == EmptyForm + ;Trace("BOOKCASE - PlacedBook17 is empty, placing book there") + PlacedBook17 = BookBase + elseif PlacedBook18 == EmptyForm + ;Trace("BOOKCASE - PlacedBook18 is empty, placing book there") + PlacedBook18 = BookBase + endif + + BookAmount = BookAmount - 1 + + endWhile +endFunction + + +Function CountMaxBooks() + ; Checks how many books can be placed on this shelf + if BookMarker01 == EmptyRef + MaxBooksAllowed = 0 + elseif BookMarker02 == EmptyRef + MaxBooksAllowed = 1 + elseif BookMarker03 == EmptyRef + MaxBooksAllowed = 2 + elseif BookMarker04 == EmptyRef + MaxBooksAllowed = 3 + elseif BookMarker05 == EmptyRef + MaxBooksAllowed = 4 + elseif BookMarker06 == EmptyRef + MaxBooksAllowed = 5 + elseif BookMarker07 == EmptyRef + MaxBooksAllowed = 6 + elseif BookMarker08 == EmptyRef + MaxBooksAllowed = 7 + elseif BookMarker09 == EmptyRef + MaxBooksAllowed = 8 + elseif BookMarker10 == EmptyRef + MaxBooksAllowed = 9 + elseif BookMarker11 == EmptyRef + MaxBooksAllowed = 10 + elseif BookMarker12 == EmptyRef + MaxBooksAllowed = 11 + elseif BookMarker13 == EmptyRef + MaxBooksAllowed = 12 + elseif BookMarker14 == EmptyRef + MaxBooksAllowed = 13 + elseif BookMarker15 == EmptyRef + MaxBooksAllowed = 14 + elseif BookMarker16 == EmptyRef + MaxBooksAllowed = 15 + elseif BookMarker17 == EmptyRef + MaxBooksAllowed = 16 + elseif BookMarker18 == EmptyRef + MaxBooksAllowed = 17 + elseif BookMarker18 + MaxBooksAllowed = 18 + endif + ;Trace("BOOKCASE - " + MaxBooksAllowed + " books can be placed on this shelf") +endFunction + + +ObjectReference Function UpdateSingleBook(Form TargetBook, ObjectReference PlacedBookRef, ObjectReference TargetMarker) + ObjectReference retVal ; We return the book we placed (or None) + ; Note - it would be more efficient to move the book to its home position if the desired + ; book matches the placed book, but MoveTo doesn't work correctly with multi-part dynamic + ; objects. So we sidestep the issue by always deleting and placing + if PlacedBookRef + PlacedBookRef.Disable() + PlacedBookRef.Delete() + endIf + if TargetBook + retVal = TargetMarker.PlaceAtMe(TargetBook) + retVal.BlockActivation() + endIf + return retVal +EndFunction + + +Function UpdateBooks() + GoToState("PlacingBooks") ; Future calls should not mess with this stuff + + PlacedBook01Ref = UpdateSingleBook(PlacedBook01, PlacedBook01Ref, BookMarker01) + PlacedBook02Ref = UpdateSingleBook(PlacedBook02, PlacedBook02Ref, BookMarker02) + PlacedBook03Ref = UpdateSingleBook(PlacedBook03, PlacedBook03Ref, BookMarker03) + PlacedBook04Ref = UpdateSingleBook(PlacedBook04, PlacedBook04Ref, BookMarker04) + PlacedBook05Ref = UpdateSingleBook(PlacedBook05, PlacedBook05Ref, BookMarker05) + + PlacedBook06Ref = UpdateSingleBook(PlacedBook06, PlacedBook06Ref, BookMarker06) + PlacedBook07Ref = UpdateSingleBook(PlacedBook07, PlacedBook07Ref, BookMarker07) + PlacedBook08Ref = UpdateSingleBook(PlacedBook08, PlacedBook08Ref, BookMarker08) + PlacedBook09Ref = UpdateSingleBook(PlacedBook09, PlacedBook09Ref, BookMarker09) + PlacedBook10Ref = UpdateSingleBook(PlacedBook10, PlacedBook10Ref, BookMarker10) + + PlacedBook11Ref = UpdateSingleBook(PlacedBook11, PlacedBook11Ref, BookMarker11) + PlacedBook12Ref = UpdateSingleBook(PlacedBook12, PlacedBook12Ref, BookMarker12) + PlacedBook13Ref = UpdateSingleBook(PlacedBook13, PlacedBook13Ref, BookMarker13) + PlacedBook14Ref = UpdateSingleBook(PlacedBook14, PlacedBook14Ref, BookMarker14) + PlacedBook15Ref = UpdateSingleBook(PlacedBook15, PlacedBook15Ref, BookMarker15) + + PlacedBook16Ref = UpdateSingleBook(PlacedBook16, PlacedBook16Ref, BookMarker16) + PlacedBook17Ref = UpdateSingleBook(PlacedBook17, PlacedBook17Ref, BookMarker17) + PlacedBook18Ref = UpdateSingleBook(PlacedBook18, PlacedBook18Ref, BookMarker18) + + UnBlockActivate() ; Allow the player to mess with them + GoToState("") ; Now allow books to be updated again +EndFunction + +State PlacingBooks + Function UpdateBooks() + ; Already updating books, so ignore + EndFunction +EndState + \ No newline at end of file diff --git a/source/scripts/playerbookshelftriggerscript.psc b/source/scripts/playerbookshelftriggerscript.psc new file mode 100644 index 00000000..c0a40da8 --- /dev/null +++ b/source/scripts/playerbookshelftriggerscript.psc @@ -0,0 +1,63 @@ +Scriptname PlayerBookShelfTriggerSCRIPT extends ObjectReference + +import debug +import utility + +ObjectReference Property ShelfContainer auto hidden + +Bool Property AlreadyLoaded = FALSE Auto Hidden + + +EVENT OnCellLoad() + if AlreadyLoaded == FALSE + ShelfContainer = GetLinkedRef() + AlreadyLoaded = TRUE + endif +endEVENT + + +auto STATE WaitForBooks + + EVENT OnBeginState() + ;Trace(self + " BOOKTRIGGER - Waiting For Books!") + endEVENT + + EVENT OnTriggerEnter(ObjectReference TriggerRef) + ;Trace("DARYL - " + self + " Reference " + TriggerRef + " has ENTERED") + + endEvent + + EVENT OnTriggerLeave(ObjectReference TriggerRef) + ; Reference has left this trigger + if GetParentCell().IsAttached() + ;Trace("DARYL - " + self + " Reference " + TriggerRef + " has EXITED") + if (TriggerRef == Game.GetPlayerGrabbedRef()) + ; Check to see if the player is holding it + ;Trace("DARYL - " + self + " Player has a hold of this reference, do nothing") + else + ; Player isnt' grabbing this reference, check to see if it's in the container. + if Shelfcontainer.GetItemCount(TriggerRef.GetBaseObject()) >= 1 + Shelfcontainer.RemoveItem(TriggerRef.GetBaseObject(), 1) + (Shelfcontainer as PlayerBookShelfContainerScript).CurrentBookAmount = (Shelfcontainer as PlayerBookShelfContainerScript).CurrentBookAmount - 1 + (ShelfContainer as PlayerBookShelfContainerScript).RemoveBooks((TriggerRef.GetBaseObject()), 1) + else + ; There is no book based on this form in the container + ;Trace("DARYL - " + self + " Container doesn't contain this book") + endif + endif + endif + endEvent + + +endSTATE + + +STATE IgnoreBooks + Event OnBeginState() + ;Trace(self + " BOOKTRIGGER - Ignoring Books!") + endEVENT +endSTATE + + + +int Property testint Auto diff --git a/source/scripts/playerpotionrackclicktriggerscript.psc b/source/scripts/playerpotionrackclicktriggerscript.psc new file mode 100644 index 00000000..29a1aee0 --- /dev/null +++ b/source/scripts/playerpotionrackclicktriggerscript.psc @@ -0,0 +1,26 @@ +Scriptname PlayerPotionRackClickTriggerScript extends ObjectReference + +import debug +import utility + +ObjectReference Property ShelfContainer auto hidden + +Keyword Property BookShelfContainer Auto + +Bool Property AlreadyLoaded = FALSE Auto Hidden + + +EVENT OnCellLoad() + if AlreadyLoaded == FALSE + ShelfContainer = GetLinkedRef(BookShelfContainer) + AlreadyLoaded = TRUE + endif +endEVENT + + +EVENT OnActivate(ObjectReference TriggerRef) + + Trace("DARYL - " + self + " I've been activated, opening container: " + ShelfContainer) + ShelfContainer.Activate(Game.GetPlayer(), FALSE) + +endEVENT diff --git a/source/scripts/playerpotionracktriggerscript.psc b/source/scripts/playerpotionracktriggerscript.psc new file mode 100644 index 00000000..870a15ef --- /dev/null +++ b/source/scripts/playerpotionracktriggerscript.psc @@ -0,0 +1,47 @@ +Scriptname PlayerPotionRackTriggerScript extends ObjectReference + +import debug +import utility + +ObjectReference Property ShelfContainer auto hidden + +Bool Property AlreadyLoaded = FALSE Auto Hidden + + +EVENT OnCellLoad() + if AlreadyLoaded == FALSE + ShelfContainer = GetLinkedRef() + AlreadyLoaded = TRUE + endif +endEVENT + + +STATE WaitForBooks + + EVENT OnBeginState() + trace(self + " BOOKTRIGGER - Waiting For Books!") + endEVENT + + EVENT OnTriggerEnter(ObjectReference TriggerRef) + Trace("DARYL - " + self + " Reference " + TriggerRef + " has ENTERED") + + endEvent + + EVENT OnTriggerLeave(ObjectReference TriggerRef) + Trace("DARYL - " + self + " Reference " + TriggerRef + " has EXITED") + Shelfcontainer.RemoveItem(TriggerRef.GetBaseObject(), 1) + (Shelfcontainer as PlayerBookShelfContainerScript).CurrentBookAmount = (Shelfcontainer as PlayerBookShelfContainerScript).CurrentBookAmount - 1 + (ShelfContainer as PlayerBookShelfContainerScript).RemoveBooks((TriggerRef.GetBaseObject()), 1) + endEvent + + +endSTATE + + +auto STATE IgnoreBooks + Event OnBeginState() + trace(self + " BOOKTRIGGER - Ignoring Books!") + endEVENT +endSTATE + + diff --git a/source/scripts/playerwerewolfchangescript.psc b/source/scripts/playerwerewolfchangescript.psc new file mode 100644 index 00000000..ebbbd9a2 --- /dev/null +++ b/source/scripts/playerwerewolfchangescript.psc @@ -0,0 +1,478 @@ +Scriptname PlayerWerewolfChangeScript extends Quest + +float Property StandardDurationSeconds auto +{How long (in real seconds) the transformation lasts} + +float Property DurationWarningTimeSeconds auto +{How long (in real seconds) before turning back we should warn the player} + +float Property FeedExtensionTimeSeconds auto +{How long (in real seconds) that feeding extends werewolf time} + +VisualEffect property FeedBloodVFX auto +{Visual Effect on Wolf for Feeding Blood} + +Race Property WerewolfBeastRace auto +ObjectReference Property LycanStash auto +Perk Property PlayerWerewolfFeed auto + +Faction Property PlayerWerewolfFaction auto +Faction Property WerewolfFaction auto + +Message Property PlayerWerewolfExpirationWarning auto +Message Property PlayerWerewolfFeedMessage auto +GlobalVariable Property GameDaysPassed auto +GlobalVariable Property TimeScale auto +GlobalVariable Property PlayerWerewolfShiftBackTime auto + +ImageSpaceModifier Property WerewolfWarn auto +ImageSpaceModifier Property WerewolfChange auto + +Race Property WerewolfRace auto +Sound Property NPCWerewolfTransformation auto +Sound Property WerewolfIMODSound auto +Idle Property WerewolfTransformBack auto +Idle Property SpecialFeeding auto + +Quest Property CompanionsTrackingQuest auto +Quest Property C03Rampage auto + +Shout Property CurrentHowl auto +WordOfPower Property CurrentHowlWord1 auto +WordOfPower Property CurrentHowlWord2 auto +WordOfPower Property CurrentHowlWord3 auto + +Spell Property PlayerWerewolfLvl10AndBelowAbility auto +Spell Property PlayerWerewolfLvl15AndBelowAbility auto +Spell Property PlayerWerewolfLvl20AndBelowAbility auto +Spell Property PlayerWerewolfLvl25AndBelowAbility auto +Spell Property PlayerWerewolfLvl30AndBelowAbility auto +Spell Property PlayerWerewolfLvl35AndBelowAbility auto +Spell Property PlayerWerewolfLvl40AndBelowAbility auto +Spell Property PlayerWerewolfLvl45AndBelowAbility auto +Spell Property PlayerWerewolfLvl50AndOverAbility auto + +Spell Property FeedBoost auto +Spell property BleedingFXSpell auto +{This Spell is for making the target of feeding bleed.} + +Armor Property WolfSkinFXArmor auto + +bool Property Untimed auto + +FormList Property CrimeFactions auto +FormList Property WerewolfDispelList auto + +float __durationWarningTime = -1.0 +float __feedExtensionTime = -1.0 +float __gorgeExtensionTime = -1.0 +bool __tryingToShiftBack = false +bool __shiftingBack = false +bool __shuttingDown = false +bool __trackingStarted = false + +float Function RealTimeSecondsToGameTimeDays(float realtime) + float scaledSeconds = realtime * TimeScale.Value + return scaledSeconds / (60 * 60 * 24) +EndFunction + +float Function GameTimeDaysToRealTimeSeconds(float gametime) + float gameSeconds = gametime * (60 * 60 * 24) + return (gameSeconds / TimeScale.Value) +EndFunction + +Function PrepShift() +; Debug.Trace("WEREWOLF: Prepping shift...") + Actor player = Game.GetPlayer() + + ; sets up the UI restrictions + Game.SetBeastForm(True) + Game.EnableFastTravel(False) + + ; set up perks/abilities + ; (don't need to do this anymore since it's on from gamestart) + ; Game.GetPlayer().AddPerk(PlayerWerewolfFeed) + + ; screen effect + WerewolfChange.Apply() + WerewolfIMODSound.Play(Game.GetPlayer()) + + ; get rid of your summons + int count = 0 + while (count < WerewolfDispelList.GetSize()) + Spell gone = WerewolfDispelList.GetAt(count) as Spell + if (gone != None) + Game.GetPlayer().DispelSpell(gone) + endif + count += 1 + endwhile + + + Game.DisablePlayerControls(abMovement = false, abFighting = false, abCamSwitch = true, abMenu = false, abActivate = false, abJournalTabs = false, aiDisablePOVType = 1) + Game.ForceThirdPerson() + Game.ShowFirstPersonGeometry(false) +EndFunction + +Function InitialShift() +; Debug.Trace("WEREWOLF: Player beginning transformation.") + + WerewolfWarn.Apply() + + if (Game.GetPlayer().IsDead()) +; Debug.Trace("WEREWOLF: Player is dead; bailing out.") + return + endif + + ; actual switch + Game.GetPlayer().SetRace(WerewolfBeastRace) +EndFunction + +Function StartTracking() + if (__trackingStarted) + return + endif + + __trackingStarted = true + +; Debug.Trace("WEREWOLF: Race swap done; starting tracking and effects.") + + ; take all the player's stuff (since he/she can't use it anyway) + ; Game.GetPlayer().RemoveAllItems(LycanStash) + Game.GetPlayer().UnequipAll() + Game.GetPlayer().EquipItem(WolfSkinFXArmor, False, True) + + ;Add Blood Effects + ;FeedBloodVFX.Play(Game.GetPlayer()) + + ; make everyone hate you + Game.GetPlayer().SetAttackActorOnSight(true) + + ; alert anyone nearby that they should now know the player is a werewolf + Game.SendWereWolfTransformation() + + Game.GetPlayer().AddToFaction(PlayerWerewolfFaction) + Game.GetPlayer().AddToFaction(WerewolfFaction) + int cfIndex = 0 + while (cfIndex < CrimeFactions.GetSize()) +; Debug.Trace("WEREWOLF: Setting enemy flag on " + CrimeFactions.GetAt(cfIndex)) + (CrimeFactions.GetAt(cfIndex) as Faction).SetPlayerEnemy() + cfIndex += 1 + endwhile + + ; but they also don't know that it's you + Game.SetPlayerReportCrime(false) + + ; recalc times + __durationWarningTime = RealTimeSecondsToGameTimeDays(DurationWarningTimeSeconds) + __feedExtensionTime = RealTimeSecondsToGameTimeDays(FeedExtensionTimeSeconds) + __gorgeExtensionTime = RealTimeSecondsToGameTimeDays(DLC1GorgingDurationSeconds) + + ; unequip magic + Spell left = Game.GetPlayer().GetEquippedSpell(0) + Spell right = Game.GetPlayer().GetEquippedSpell(1) + Spell power = Game.GetPlayer().GetEquippedSpell(2) + Shout voice = Game.GetPlayer().GetEquippedShout() + if (left != None) + Game.GetPlayer().UnequipSpell(left, 0) + endif + if (right != None) + Game.GetPlayer().UnequipSpell(right, 1) + endif + if (power != None) + ; some players are overly clever and sneak a power equip between casting + ; beast form and when we rejigger them there. this will teach them. +; Debug.Trace("WEREWOLF: " + power + " was equipped; removing.") + Game.GetPlayer().UnequipSpell(power, 2) + else +; Debug.Trace("WEREWOLF: No power equipped.") + endif + if (voice != None) + ; same deal here, but for shouts +; Debug.Trace("WEREWOLF: " + voice + " was equipped; removing.") + Game.GetPlayer().UnequipShout(voice) + else +; Debug.Trace("WEREWOLF: No shout equipped.") + endif + + ; but make up for it by giving you the sweet howl + CurrentHowlWord1 = (CompanionsTrackingQuest as CompanionsHousekeepingScript).CurrentHowlWord1 + CurrentHowlWord2 = (CompanionsTrackingQuest as CompanionsHousekeepingScript).CurrentHowlWord2 + CurrentHowlWord3 = (CompanionsTrackingQuest as CompanionsHousekeepingScript).CurrentHowlWord3 + CurrentHowl = (CompanionsTrackingQuest as CompanionsHousekeepingScript).CurrentHowl + + Game.UnlockWord(CurrentHowlWord1) + Game.UnlockWord(CurrentHowlWord2) + Game.UnlockWord(CurrentHowlWord3) + Game.GetPlayer().AddShout(CurrentHowl) + Game.GetPlayer().EquipShout(CurrentHowl) + + ; and some rad claws + int playerLevel = Game.GetPlayer().GetLevel() + if (playerLevel <= 10) + Game.GetPlayer().AddSpell(PlayerWerewolfLvl10AndBelowAbility, false) + elseif (playerLevel <= 15) + Game.GetPlayer().AddSpell(PlayerWerewolfLvl15AndBelowAbility, false) + elseif (playerLevel <= 20) + Game.GetPlayer().AddSpell(PlayerWerewolfLvl20AndBelowAbility, false) + elseif (playerLevel <= 25) + Game.GetPlayer().AddSpell(PlayerWerewolfLvl25AndBelowAbility, false) + elseif (playerLevel <= 30) + Game.GetPlayer().AddSpell(PlayerWerewolfLvl30AndBelowAbility, false) + elseif (playerLevel <= 35) + Game.GetPlayer().AddSpell(PlayerWerewolfLvl35AndBelowAbility, false) + elseif (playerLevel <= 40) + Game.GetPlayer().AddSpell(PlayerWerewolfLvl40AndBelowAbility, false) + elseif (playerLevel <= 45) + Game.GetPlayer().AddSpell(PlayerWerewolfLvl45AndBelowAbility, false) + else + Game.GetPlayer().AddSpell(PlayerWerewolfLvl50AndOverAbility, false) + endif + + ; calculate when the player turns back into a pumpkin + float currentTime = GameDaysPassed.GetValue() + float regressTime = currentTime + RealTimeSecondsToGameTimeDays(StandardDurationSeconds) + PlayerWerewolfShiftBackTime.SetValue(regressTime) +; Debug.Trace("WEREWOLF: Current day -- " + currentTime) +; Debug.Trace("WEREWOLF: Player will turn back at day " + regressTime) + + ; increment stats + Game.IncrementStat("Werewolf Transformations") + + ; set us up to check when we turn back + RegisterForUpdate(5) + + SetStage(10) ; we're done with the transformation handling +EndFunction + + +Event OnUpdate() + if (Untimed) + return + endif +; Debug.Trace("WEREWOLF: NumWerewolfPerks = " + Game.QueryStat("NumWerewolfPerks")) + if Game.QueryStat("NumWerewolfPerks") >= DLC1WerewolfMaxPerks.Value +; debug.trace("WEREWOLF: achievement granted") + Game.AddAchievement(57) + endif + + float currentTime = GameDaysPassed.GetValue() + float regressTime = PlayerWerewolfShiftBackTime.GetValue() + + if ( (currentTime >= regressTime) && (!Game.GetPlayer().IsInKillMove()) && !__tryingToShiftBack ) + UnregisterForUpdate() + SetStage(100) ; time to go, buddy + return + endif + + if (currentTime >= regressTime - __durationWarningTime) + if (GetStage() == 10) + SetStage(20) ; almost there + return + endif + endif + +; Debug.Trace("WEREWOLF: Checking, still have " + GameTimeDaysToRealTimeSeconds(regressTime - currentTime) + " seconds to go.") +EndEvent + +Function SetUntimed(bool untimedValue) + Untimed = untimedValue + if (Untimed) + UnregisterForUpdate() + endif +EndFunction + +; called from stage 11 +Function Feed(Actor victim) +; Debug.Trace("WEREWOLF: start newShiftTime = " + GameTimeDaysToRealTimeSeconds(PlayerWerewolfShiftBackTime.GetValue()) + ", __feedExtensionTime = " + GameTimeDaysToRealTimeSeconds(__feedExtensionTime)) + float newShiftTime = PlayerWerewolfShiftBackTime.GetValue() + __feedExtensionTime / 2 + if victim.HasKeyword(ActorTypeNPC) + newShiftTime =newShiftTime + __feedExtensionTime / 2 +; Debug.Trace("WEREWOLF: victim is NPC") + endif +; Debug.Trace("WEREWOLF: default newShiftTime = " + GameTimeDaysToRealTimeSeconds(newShiftTime) + ", __feedExtensionTime = " + GameTimeDaysToRealTimeSeconds(__feedExtensionTime)) + if Game.GetPlayer().HasPerk(DLC1GorgingPerk) == 1 + newShiftTime = newShiftTime + __GorgeExtensionTime / 2 + if victim.HasKeyword(ActorTypeNPC) + newShiftTime = newShiftTime + __GorgeExtensionTime / 2 + endif + endif + Game.GetPlayer().PlayIdle(SpecialFeeding) + + ;This is for adding a spell that simulates bleeding + BleedingFXSpell.Cast(victim,victim) + + if (!C03Rampage.IsRunning()) + PlayerWerewolfShiftBackTime.SetValue(newShiftTime) + PlayerWerewolfFeedMessage.Show() + FeedBoost.Cast(Game.GetPlayer()) + ; victim.SetActorValue("Variable08", 100) +; Debug.Trace("WEREWOLF: Player feeding -- new regress day is " + newShiftTime) + endif + SetStage(10) +EndFunction + + +; called from stage 20 +Function WarnPlayer() +; Debug.Trace("WEREWOLF: Player about to transform back.") + WerewolfWarn.Apply() +EndFunction + + +; called from stage 100 +Function ShiftBack() + __tryingToShiftBack = true + + while (Game.GetPlayer().GetAnimationVariableBool("bIsSynced")) +; Debug.Trace("WEREWOLF: Waiting for synced animation to finish...") + Utility.Wait(0.1) + endwhile +; Debug.Trace("WEREWOLF: Sending transform event to turn player back to normal.") + + __shiftingBack = false + ; RegisterForAnimationEvent(Game.GetPlayer(), "TransformToHuman") + ; Game.GetPlayer().PlayIdle(WerewolfTransformBack) + ; Utility.Wait(10) + ActuallyShiftBackIfNecessary() +EndFunction + +Event OnAnimationEvent(ObjectReference akSource, string asEventName) + if (asEventName == "TransformToHuman") + ActuallyShiftBackIfNecessary() + endif +EndEvent + +Function ActuallyShiftBackIfNecessary() + if (__shiftingBack) + return + endif + + __shiftingBack = true + +; Debug.Trace("WEREWOLF: Player returning to normal.") + + Game.SetInCharGen(true, true, false) + + UnRegisterForAnimationEvent(Game.GetPlayer(), "TransformToHuman") + UnRegisterForUpdate() ; just in case + + if (Game.GetPlayer().IsDead()) +; Debug.Trace("WEREWOLF: Player is dead; bailing out.") + return + endif + + ;Remove Blood Effects + ;FeedBloodVFX.Stop(Game.GetPlayer()) + + ; imod + WerewolfChange.Apply() + WerewolfIMODSound.Play(Game.GetPlayer()) + + ; get rid of your summons if you have any + int count = 0 + while (count < WerewolfDispelList.GetSize()) + Spell gone = WerewolfDispelList.GetAt(count) as Spell + if (gone != None) +; Debug.Trace("WEREWOLF: Dispelling " + gone) + Game.GetPlayer().DispelSpell(gone) + endif + count += 1 + endwhile + + ; make sure the transition armor is gone. We RemoveItem here, because the SetRace stored all equipped items + ; at that time, and we equip this armor prior to setting the player to a beast race. When we switch back, + ; if this were still in the player's inventory it would be re-equipped. + Game.GetPlayer().RemoveItem(WolfSkinFXArmor, 1, True) + + ; clear out perks/abilities + ; (don't need to do this anymore since it's on from gamestart) + ; Game.GetPlayer().RemovePerk(PlayerWerewolfFeed) + + ; make sure your health is reasonable before turning you back + ; Game.GetPlayer().GetActorBase().SetInvulnerable(true) + Game.GetPlayer().SetGhost() + float currHealth = Game.GetPlayer().GetAV("health") + if (currHealth <= 101) +; Debug.Trace("WEREWOLF: Player's health is only " + currHealth + "; restoring.") + Game.GetPlayer().RestoreAV("health", 101 - currHealth) + endif + + ; change you back +; Debug.Trace("WEREWOLF: Setting race " + (CompanionsTrackingQuest as CompanionsHousekeepingScript).PlayerOriginalRace + " on " + Game.GetPlayer()) + Game.GetPlayer().SetRace((CompanionsTrackingQuest as CompanionsHousekeepingScript).PlayerOriginalRace) + ; release the player controls +; Debug.Trace("WEREWOLF: Restoring camera controls") + Game.EnablePlayerControls(abMovement = false, abFighting = false, abCamSwitch = true, abLooking = false, abSneaking = false, abMenu = false, abActivate = false, abJournalTabs = false, aiDisablePOVType = 1) + Game.ShowFirstPersonGeometry(true) + + ; no more howling for you + Game.GetPlayer().UnequipShout(CurrentHowl) + Game.GetPlayer().RemoveShout(CurrentHowl) + + ; or those claws + Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl10AndBelowAbility) + Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl15AndBelowAbility) + Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl20AndBelowAbility) + Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl25AndBelowAbility) + Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl30AndBelowAbility) + Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl35AndBelowAbility) + Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl40AndBelowAbility) + Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl45AndBelowAbility) + Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl50AndOverAbility) + + ; gimme back mah stuff + ; LycanStash.RemoveAllItems(Game.GetPlayer()) + + ; people don't hate you no more + Game.GetPlayer().SetAttackActorOnSight(false) + Game.GetPlayer().RemoveFromFaction(PlayerWerewolfFaction) + Game.GetPlayer().RemoveFromFaction(WerewolfFaction) + int cfIndex = 0 + while (cfIndex < CrimeFactions.GetSize()) +; Debug.Trace("WEREWOLF: Removing enemy flag from " + CrimeFactions.GetAt(cfIndex)) + (CrimeFactions.GetAt(cfIndex) as Faction).SetPlayerEnemy(false) + cfIndex += 1 + endwhile + + ; and you're now recognized + Game.SetPlayerReportCrime(true) + + ; alert anyone nearby that they should now know the player is a werewolf + Game.SendWereWolfTransformation() + + ; give the set race event a chance to come back, otherwise shut us down + Utility.Wait(5) + Shutdown() +EndFunction + +Function Shutdown() + if (__shuttingDown) + return + endif + + __shuttingDown = true + + Game.GetPlayer().GetActorBase().SetInvulnerable(false) + Game.GetPlayer().SetGhost(false) + + Game.SetBeastForm(False) + Game.EnableFastTravel(True) + + Game.SetInCharGen(false, false, false) + + Stop() +EndFunction + +Float Property DLC1GorgingDurationSeconds Auto + +Perk Property DLC1GorgingPerk Auto + +Perk Property DLC1SavageFeedingPerk Auto + +Keyword Property ActorTypeNPC Auto + +Perk Property DLC1AnimalVigor Auto + +GlobalVariable Property DLC1WerewolfTotalPerksEarned Auto + +GlobalVariable Property DLC1WerewolfMaxPerks Auto diff --git a/source/scripts/pressureplate.psc b/source/scripts/pressureplate.psc new file mode 100644 index 00000000..e0dc247c --- /dev/null +++ b/source/scripts/pressureplate.psc @@ -0,0 +1,68 @@ +scriptName PressurePlate extends TrapTriggerBase +; +; +; +;================================================================ + +weapon property pressEffect auto +ammo property pressEffectAmmo auto + +State Active + Event onBeginState() + objectReference selfRef = self + goToState( "DoNothing" ) + ;pressEffect.fire(selfRef, pressEffectAmmo) + ; EFFECT IS HERE ^^^^^ UNCOMMENT ONCE PROJECTILES OR PARTICLES CAN LEAVE A TRIGGER BOX CORRECTLY +; debug.Trace(self + ": is calling onBeginState Active") +; debug.Trace(self + ": StoredTriggerType = " + StoredTriggerType + ", objectsInTrigger = " + objectsInTrigger) + if (StoredTriggerType == 1) + Type = 3 + utility.wait(0.1) + activate(self as objectReference) + utility.wait(0.1) + ;Type = 1 + else + activate(self as objectReference) + endif + ;playAnimationAndWait( "trigger", "reset" ) + TriggerSound.play(self) + playAnimation("Down") + if objectsInTrigger == 0 + goToState( "Inactive" ) + playAnimation("Up") + endif + endEvent + + event OnTriggerEnter( objectReference triggerRef ) +; ;debug.TRACE(self + " has been entered by " + triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + endEvent + + event OnTriggerLeave( objectReference triggerRef ) +; ;debug.TRACE(self + " has been exited by " + triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + if objectsInTrigger == 0 + goToState ("Inactive") + playAnimation("Up") + endif + endEvent +endState + +State DoNothing ;Dummy state, don't do anything if animating + event OnTriggerEnter( objectReference triggerRef ) +; debug.TRACE(self + " has been entered by " + triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + endEvent + + event OnTrigger( objectReference triggerRef ) + endEvent + + event OnTriggerLeave( objectReference triggerRef ) +; debug.TRACE(self + " has been exited by " + triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + if objectsInTrigger == 0 + goToState ("Inactive") + playAnimation("Up") + endif + endEvent +EndState diff --git a/source/scripts/pressurereleaseplate.psc b/source/scripts/pressurereleaseplate.psc new file mode 100644 index 00000000..56671454 --- /dev/null +++ b/source/scripts/pressurereleaseplate.psc @@ -0,0 +1,169 @@ +scriptName PressureReleasePlate extends TrapTriggerBase +; +; +;====================================================== + +import debug + +int Count ;if Finite = 1, Determines how many times this trigger can be used +int CountUsed ;Used to compare times triggered to max triggers allowed +int Type ;This is to determine trigger to send to the trap +bool bdownVar = true + +weapon property pressEffect auto +ammo property pressEffectAmmo auto +bool property DoNotAllowActors = FALSE auto hidden +objectReference property selfRef auto hidden + +; Property to represent the animation state of the pressure plate. If true the plate is down. +; Setting this property will also ansure the object is animated to the right state. +bool property bDown + bool Function Get() + return bdownVar + endFunction + + ; Set the down state and send playAnimation event if state changed. + Function Set(bool bValue) + ;if (bdownVar != bValue) + + if (bValue == true) + ;TraceStack("Playing Down") + playAnimation("Down") + goToState("Inactive") + else + ;TraceStack("Playing Up") + playAnimation("Up") + goToState("Active") + endif + + bdownVar = bValue + ;endif + endFunction +endProperty + +Event onCellAttach() +; debug.Trace(self + ": onCellAttach called") + selfRef = self as objectReference + objectsInTrigger = self.GetTriggerObjectCount() + if (objectsInTrigger > 0) + bDown = true + ;goToState("Inactive") + else + bDown = false + ;goToState("Active") + endif +endevent + +; We are in the inactive state when something is in the trigger and the pressure plate is in the down position. +; This is the default state. +auto State Inactive + event OnTriggerEnter (objectReference triggerRef) + +; debug.TRACE(self + " in state Inactive has been entered by " + triggerRef) + + ;lastTriggerRef = triggerRef + objectsInTrigger = self.GetTriggerObjectCount() + + ;Something has entered so we are going to push down. + if (objectsInTrigger > 0) + ;/ + if (bDown == false) + ;if (FiniteUse == TRUE && CountUsed < Count);if finite use and count > count used + ; CountUsed += 1 ;increase count for hold type triggers + ;endif + +; ;debug.Trace(self + ": has activated in Inactive onTriggerEnter") + ;activate(selfRef) + bDown = true + endif + /; + endif + endevent + + event OnTriggerLeave (objectReference triggerRef) +; debug.TRACE(self + " in state Inactive has been exited by " + triggerRef) + + ;lastTriggerRef = triggerRef + objectsInTrigger = self.GetTriggerObjectCount() + + ; If no objects left in the trigger then set to the active state. + if (objectsInTrigger == 0) + bDown = false + ;goToState( "Active" ) + + ;if (FiniteUse == FALSE) + ;TRACE("Infinite Use") + ; goToState( "Active" ) + ;endif + endif + endevent +endstate + +; We are in the active state when nothing is in the trigger and the pressure plate is in the up position. +State Active + Event onBeginState() + if !selfRef + selfRef = self as objectReference + endif + ;pressEffect.fire(selfRef, pressEffectAmmo) + ; EFFECT IS HERE ^^^^^ UNCOMMENT ONCE PROJECTILES OR PARTICLES CAN LEAVE A TRIGGER BOX CORRECTLY +; debug.Trace(self + ": has activated in Active onBeginState") + activate(selfRef) + + ; If used as many times as we wished then set inactive. + if (Type != 1) ;type 1 = hold so only increase on leave + CountUsed += 1 ;increase count used + endif + + if (FiniteUse == TRUE && CountUsed >= Count) + ;TRACE("Finite use amount reached, going inactive.") + goToState( "DoNothing" ) + endif + endEvent + + event OnTriggerEnter( objectReference triggerRef ) +; debug.TRACE(self + " in state Active has been entered by " + triggerRef) + + objectsInTrigger = self.GetTriggerObjectCount() + + ;This will always be true. + if (objectsInTrigger > 0) + bDown = true + ;goToState ("Inactive") + endif + endEvent + + event OnTriggerLeave( objectReference triggerRef ) +; debug.TRACE(self + " in state Active has been exited by " + triggerRef) + + objectsInTrigger = self.GetTriggerObjectCount() + + ;This is just to make sure but bDowns should already be false if we are still in the active state. + if (objectsInTrigger == 0) + bDown = false + endif + endEvent +endState + +State DoNothing ;Dummy state, don't do anything if animating + event OnTriggerEnter( objectReference triggerRef ) +; debug.TRACE(self + " in state DoNothing has been entered by " + triggerRef) + ;Put this in to make the trigger animate even when doing nothing. + ;bDown = true + endEvent + + event OnTriggerLeave( objectReference triggerRef ) +; debug.TRACE(self + " in state DoNothing has been exited by " + triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + ;Put this in to make the trigger animate even when doing nothing. + ;if (objectsInTrigger == 0) + ; bDown = false + ;endif + endEvent +EndState + +event onReset() + CountUsed = 0 + self.Reset() + goToState("Inactive") +endEvent diff --git a/source/scripts/reanimateashpile.psc b/source/scripts/reanimateashpile.psc new file mode 100644 index 00000000..f71f6ec8 --- /dev/null +++ b/source/scripts/reanimateashpile.psc @@ -0,0 +1,119 @@ +Scriptname ReanimateAshPile extends ActiveMagicEffect + +{Scripted effect for on death ash pile} + +import debug +import FormList + +;======================================================================================; +; PROPERTIES / +;=============/ + +float property fDelay = 0.75 auto + {time to wait before Spawning Ash Pile} +float property fDelayEnd = 1.65 auto + {time to wait before Removing Base Actor} +float property ShaderDuration = 0.00 auto + {Duration of Effect Shader.} +Activator property AshPileObject auto + {The object we use as a pile.} +EffectShader property MagicEffectShader auto + {The Effect Shader we want.} +Bool property bSetAlphaZero = True auto + {The Effect Shader we want.} +FormList Property ImmunityList auto + {If the target is in this list, they will not be disintegrated.} +Bool property bSetAlphaToZeroEarly = False Auto + {Use this if we want to set the acro to invisible somewhere before the effect shader is done.} +Keyword Property ActorTypeDaedra Auto + +Keyword Property ActorTypeFamiliar Auto + +bool Property AshPileCreated Auto + + +;======================================================================================; +; VARIABLES / +;=============/ + + +actor Victim +race VictimRace +bool TargetIsImmune = False + +;============= +; FUNCTIONS / +;============= + +bool function IsSummoned() + if Victim.HasKeyword(ActorTypeFamiliar) || Victim.HasKeyword(ActorTypeDaedra) + return true +; ; debug.trace("ReanimateAshPile: IsSummoned True") + else + return false +; ; debug.trace("ReanimateAshPile: IsSummoned False") + endIf +endFunction + +bool function TurnToAsh() + trace("victim just died") + victim.SetCriticalStage(Victim.CritStage_DisintegrateStart) +; victim.SetAlpha (0.99,False) + if MagicEffectShader != none + MagicEffectShader.play(Victim,ShaderDuration) + endif + if bSetAlphaToZeroEarly + victim.SetAlpha (0.0,True) + endif + utility.wait(fDelay) + Victim.AttachAshPile(AshPileObject) +; AshPileRef = AshPileObject +; AshPileRef.SetAngle(0.0,0.0,(Victim.GetAngleZ())) + utility.wait(fDelayEnd) + if MagicEffectShader != none + MagicEffectShader.stop(Victim) + endif + if bSetAlphaZero == True + victim.SetAlpha (0.0,True) + endif + victim.SetCriticalStage(Victim.CritStage_DisintegrateEnd) + +endFunction + +;======================================================================================; +; EVENTS / +;=============/ + +Event OnEffectStart(Actor Target, Actor Caster) + victim = target +; debug.trace("ReanimateAshpile: victim == " + victim + ", is this right?") + + if Victim.IsCommandedActor() == True && IsSummoned() == False + TargetIsImmune = False + else + TargetIsImmune = True + endIf + +EndEvent + + +Event OnDying(Actor Killer) + +; ; debug.trace("ReanimateAshPile TargetIsImmune:" + TargetIsImmune) + + if TargetIsImmune == False && AshPileCreated == False + TurnToAsh() + AshPileCreated = True + endif + +EndEvent + +Event OnEffectFinish(Actor Target, Actor Caster) + + if TargetIsImmune == False && AshPileCreated == False + TurnToAsh() + AshPileCreated = True + endif + +EndEvent + diff --git a/source/scripts/resourcefurniturescript.psc b/source/scripts/resourcefurniturescript.psc new file mode 100644 index 00000000..5516ba9a --- /dev/null +++ b/source/scripts/resourcefurniturescript.psc @@ -0,0 +1,134 @@ +Scriptname ResourceFurnitureScript extends ObjectReference Conditional +{script for furniture which the player can use to get resources} + + +formlist Property requiredItemList Auto +{required for player to use - optional} + +Message Property FailureMessage Auto +{Message to say why you can't use this without RequiredWeapon} + +MiscObject Property Resource Auto +{what you get from using this furniture} + +int Property ResourceCount = 1 Auto +{how many resources you get per use} + +int property MaxResourcePerActivation = 6 auto +{How many times can this object be used before the player has to re-activate?} + +int counter +; count up how many resources have been gathered on this go. + +faction property CurrentFollowerFaction auto +{Used to handle player followers using the furniture object} + +objectReference property NPCfollower auto hidden +{hidden property to track followers who used this} + +Event OnLoad() + BlockActivation(true) +endEvent + +Event OnUnload() + ; safety measure + UnregisterForEvents(game.getplayer()) + if NPCfollower + UnregisterForEvents(NPCfollower) + endif +endEvent + +auto STATE normal +Event OnActivate(ObjectReference akActionRef) + gotoState("busy") +; debug.trace(self + "OnActivate") + if akActionRef == Game.GetPlayer() || (akActionRef as actor).isInFaction(CurrentFollowerFaction) +; debug.trace("akActionRef is either player or a follower") + if (akActionRef as actor) != game.getPlayer() +; debug.trace("It's a follower - store in NPCfollower property") + ; if not the player, must be the follower + NPCfollower = akActionRef + endif + bool allowActivation = true + ; check if player has required item + if requiredItemList + if akActionRef.GetItemCount(requiredItemList) == 0 + if akActionRef == game.getPlayer() + ; only require the axe item for the player + allowActivation = false +; debug.trace("allowActivation = "+allowActivation) + FailureMessage.Show() + endif + endif + endif + + if allowActivation + RegisterForEvents(akActionRef) +; debug.trace(self + "player/follower activation START") + Activate(akActionRef, true) +; debug.trace(self + "player/follower activation END") + endif + else +; ;debug.trace(self + "non-follower NPC activation START") + ; just activate it + Activate(akActionRef, true) +; ;debug.trace(self + "non-follower NPC activation END") + endif + gotoState("normal") +endEvent +endState + +STATE busy + ; do nothing +endState + +Event OnAnimationEvent(ObjectReference akSource, string asEventName) +; debug.trace(self + ": animation event received=" + asEventName) + if asEventName == "AddToInventory" + akSource.AddItem(Resource, ResourceCount) + ; increment counter by however many items we just received +; debug.trace("Pre-add counter = "+counter) + counter = (counter + resourceCount) +; debug.trace("Post-add counter = "+counter) + if counter >= MaxResourcePerActivation + ; if we've bagged our limit, kick the player out. Reset timer for next activation +; debug.trace("Woodpile - player has gotten "+counter+" logs this go. Kicking out.") + counter = 0 + (akSource as actor).PlayIdle(IdleWoodchopExit) + unregisterForEvents(akSource) + endif + elseif asEventName == "IdleFurnitureExit" +; debug.trace("Resource Object Unregistering: "+self) + ; reset the counter if I exit manually + counter = 0 + UnregisterForEvents(akSource) + endif +endEvent + +bool isRegisteredForEvents = false + +function RegisterForEvents(objectReference whoToRegister) + ; centralize this + isRegisteredForEvents = true + RegisterForAnimationEvent(whoToRegister, "AddToInventory") + RegisterForAnimationEvent(whoToRegister, "SoundPlay . NPCHumanWoodChop") + RegisterForAnimationEvent(whoToRegister, "IdleFurnitureExit") +endFunction + +function UnregisterForEvents(objectReference whoToUnregister) + ; centralize this + + ; It is perfectly safe to unregister for events you never registered for, however + ; this function is called as part of OnUnload, and if this object isn't persistent + ; then it may be deleted by the time OnUnload runs, and these function calls will + ; fail. Since RegisterForAnimationEvent persists us, we know it will be safe to + ; call Unregister if we've previously Registered, even if called as a part of + ; OnUnload + if isRegisteredForEvents + isRegisteredForEvents = false + UnRegisterForAnimationEvent(whoToUnregister, "AddToInventory") + UnRegisterForAnimationEvent(whoToUnregister, "IdleFurnitureExit") + endif +endFunction + +Idle Property IdleWoodchopExit Auto diff --git a/source/scripts/resourceobjectsawmillscript.psc b/source/scripts/resourceobjectsawmillscript.psc new file mode 100644 index 00000000..1d50910f --- /dev/null +++ b/source/scripts/resourceobjectsawmillscript.psc @@ -0,0 +1,65 @@ +Scriptname ResourceObjectSawMillScript extends ResourceObjectScript conditional +{This script controls saw mills and extends ResourceObjectScript} + +;Description: +;This script is extending the parent script ResourceObjectScript.psc in which most of the properties and functions are declared. See that script for specifics. + +;*** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +;*** EVERY resource object MUST have an animation event named "DestructionComplete" that is sent when the sabotage animation is finished *** +;*** EVERY child script (like this one) MUST Register/Unregister for animation event named "DestructionComplete" in it's OnLoad/OnUnLoad events *** +;*** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +;Request: +;*** !!!! PLEASE DO NOT EDIT THIS SCRIPT WITHOUT SPEAKING TO ME FIRST. THANK YOU! --jduvall !!!! *** + + + +; ----------- +Event OnLoad() + RegisterForAnimationEvent(self, "DestructionComplete") ; sabotage complete -- *** ALL children scripts of ResourceObjectScript MUST register for this animation + + RegisterForAnimationEvent(self, "MillLogChuteIdle") ; log is loaded, ready to cut + RegisterForAnimationEvent(self, "MillLogIdleReset") ; log cutting animation complete + RegisterForAnimationEvent(self, "MillLogPileLoadStart") ; log loading animation started +endEvent + +Event OnUnload() + UnRegisterForAnimationEvent(self, "DestructionComplete") ;*** ALL children scripts of ResourceObjectScript MUST unregister for this animation + + UnRegisterForAnimationEvent(self, "MillLogChuteIdle") + UnRegisterForAnimationEvent(self, "MillLogIdleReset") + UnRegisterForAnimationEvent(self, "MillLogPileLoadStart") +endEvent + +; ----------- + + +;The parent script grabs the OnAnimationEvent and then calls this function passing in the Event Name +;The reason we do this is because the parent script needs to be the one that grabs the OnAnimationEvent to process the DestructionComplete event... but it passes along the asEventName from that event to this Function +;So by extending the ProcessAnimationEvent function in each child script, we can add control for each type of resource. +function ProcessAnimationEvent(string asEventName) +; debug.trace(self + "ProcessAnimationEvent(" + asEventName + ")") + if asEventName == "MillLogPileLoadStart" + ChangeState(busy) + elseif asEventName == "MillLogChuteIdle" + ChangeState(ready) + elseif asEventName == "MillLogIdleReset" + ChangeState(waiting) + endif +EndFunction + + +; -- called by GAME PLAY FUNCTIONS in parent script +function DestroyResource() + playAnimation("MillLogCutSabotage") + endFunction + +function RepairResource() + playAnimation("MillLogIdleReset") +endFunction + +function WorkResource() + playAnimationAndWait("MillLogChuteCut", "MillLogIdleReset") +EndFunction +; -- called by GAME PLAY FUNCTIONS above + diff --git a/source/scripts/resourceobjectscript.psc b/source/scripts/resourceobjectscript.psc new file mode 100644 index 00000000..87e0b5ad --- /dev/null +++ b/source/scripts/resourceobjectscript.psc @@ -0,0 +1,298 @@ +Scriptname ResourceObjectScript extends ObjectReference conditional +{This script controls all types of resource objects... "BASE OBJECT property" denotes a property that should be set on the BaseObject, "REFERENCE property" a property that should be set on each individual reference.} + +;Description: +;This script lives on the base object of each resource type activator. It has "Base Object" properties which should be defined on the baseobject activator, and "Reference Properties" which should be set on the reference object in the render window. +;This script will control all of the resource types, with animation scripting handled by extended (child) scripts for each type of resource. + +;Note to Designers: +;This script requires an additional "sybling" activator with the SabotageResourceActivatorScript.psc attached to prompt the player to sabotage it (it calls the TryToSabotage() function in this script.) +;You can use the ResourceState property in conditions to set up packages where you need an actor to do something in the different states (it's possible as we implement more types of resources we will need to expand the list of states) + + +;Note to Artists and Animators: +;It is unlikely you will need to edit this script. You will likely be working with a child script that extends this one to control the animation. See ResourceObjectSawMillScript.psc for an example. + +;Request: +;*** !!!! PLEASE DO NOT EDIT THIS SCRIPT WITHOUT SPEAKING TO ME FIRST. THANK YOU! --jduvall !!!! *** + + +; +;Properties to set on the base object: +CWScript Property CWS Auto +{BASE OBJECT property: Pointer to CWScript attached to the CW quest} + +Keyword Property WISabotageStart Auto +{BASE OBJECT property: Pointer to the WISabotageStart keyword, which is used to start a radiant quest WISabotage} + +Message property SabotageMessage Auto +{BASE OBJECT property: The message to display when prompting the player to sabotage this object.} + +Message property SabotageReadyMessage Auto +{BASE OBJECT property: The message to display when the object is ready to be sabotaged.} + +Message property RepairMessage Auto +{BASE OBJECT property: The message to display when prompting the player to repair this object.} + +Int Property ResourceType Auto ;1 = Wheat Mill(Farm), 2 = Saw Mill, 3 = Smelter(Mine) +{BASE OBJECT property: Which type of Resource Object am I? 1 = Wheat Mill(FARM), 2 = Saw Mill, 3 = Smelter(MINE)} + +Message property BusyMessage Auto +{BASE OBJECT property: The message to display when the player activates while in BUSY state} + +Message property ReadyMessage Auto +{BASE OBJECT property: The message to display when the player activates while in READY state} + +;Properties to be set on the reference object: +ObjectReference Property Worker Auto +{REFERENCE property: (Optional) If included, this actor will be EVPed each time the resource object changes state} + +;Hidden Properties +int Property ResourceState Auto Hidden Conditional ;values determined by needs of children scripts - usually used as variables on Actor's packages to get them to interact with various levers, etc. + +; + + +; +bool property sabotaged Auto Hidden +bool property readyForSabotage Auto Hidden + +;State Constant INTs -- used for things like conditions on packages +int property destroyed = -1 Auto Hidden +int property waiting = 0 Auto Hidden +int property busy = 1 Auto Hidden +int property ready = 2 Auto Hidden + +;State Constant STRINGs -- used for script states and console command SV readability +string property strDestroyed = "destroyed" Auto Hidden +string property strWaiting = "waiting" Auto Hidden +string property strBusy = "busy" Auto Hidden +string property strReady = "ready" Auto Hidden + +; + + +; +;Generic States +Auto State waiting +EndState + +State ready +EndState + +State destroyed +EndState + +State busy +EndState + +;call this function to change state +;the ResourceState property lives in the parent script +;the ResourceState property is used to condition worker's packages to pull lever, etc. +function ChangeState(int newState) + if newState == destroyed + gotoState(strDestroyed) + ResourceState = destroyed + + elseif newState == waiting + gotoState(strWaiting) + ResourceState = waiting + + elseif newState == busy + gotoState(strBusy) + ResourceState = busy + + elseif newState == ready + gotoState(strReady) + ResourceState = ready + + Else +; debug.trace(self + "WARNING: ChangeState() recieved unexpected newState parameter of '" + newState + "'", 2) + endif + + Actor workerActor = (Worker as Actor) + if workerActor + workerActor.EvaluatePackage() + endif +endFunction + +; + +; ----------- +Event onActivate ( objectReference triggerRef ) +; debug.trace(self + " activated by " + triggerRef) +endEvent + +State ready +; log is loaded into tray, waiting to be cut + Event onActivate ( objectReference triggerRef ) + ; if activated by an actor, do nothing special. If activated by non-actor, assume trying to saw + Actor triggerActor = triggerRef as Actor + if triggerActor == None +; debug.trace(self + "activated by something other than player") + ; saw the log: + if readyForSabotage + ChangeState(busy) + sabotage() + ChangeState(destroyed) + else + ChangeState(busy) + work() + ChangeState(waiting) + endif + elseif triggerActor == Game.GetPlayer() + ; show READY message + ReadyMessage.Show() + endif + EndEvent + +EndState + +State busy + Event onActivate ( objectReference triggerRef ) + ; if activated by an actor, do nothing special. If activated by non-actor, assume trying to saw + if triggerRef == Game.GetPlayer() + ; show BUSY message + BusyMessage.Show() + endif + EndEvent + +endState +; ----------- + + +;This intercepts all the animation events for all the types of resources, and then calls a function that needs to be defined in each of the children scripts who's parameter is the string name of the activation event +Event OnAnimationEvent(ObjectReference akSource, string asEventName) + +; debug.trace(self + "OnAnimationEvent() recieved " + asEventName) + + if asEventName == "DestructionComplete" + +; debug.trace(self + "Sabotage() setting sabotaged to true") + sabotaged = True + +; debug.trace(self + "Sabotage() calling WISabotageStart.SendStoryEvent([" + GetEditorLocation() +", [" + Self + "]])") + CWs.modObjectiveBySabotage(self) + WISabotageStart.SendStoryEvent(GetEditorLocation(), Self) + + DamageObject(9999) ;the purpose of this is to set the destroyed flag in the destruction data so that guards no longer guard it, and civil war missions no longer fill with it in aliases. + + Else + ProcessAnimationEvent(asEventName) ;THIS IS WHAT THE CHILD SCRIPT USES TO PLAY PROPER ANIMATIONS + + EndIf +EndEvent + + +; ----------- +; this function is called by the sabotage activator script +Function TryToSabotage(objectReference triggerRef) + if sabotaged + ; if already sabotaged, prompt for repair + ; TEMP -- repair will most likely happen off-screen + if (triggerRef == Game.GetPlayer() && PromptPlayerRepair()) + ; repair the mill + ChangeState(busy) + repair() + ChangeState(waiting) + Else + ;do nothing, player said "NO." + endif + else + ; if ready for sabotage, just give message + if readyForSabotage + if triggerRef == Game.GetPlayer() + SabotageReadyMessage.Show() + endif + else + ; otherwise, prompt player for choice + if triggerRef != Game.GetPlayer() || PromptPlayerSabotage() + ; get mill ready for Sabotage + readyForSabotage = true + Else + ;do nothing, player said "NO." + endif + endif + endif +endFunction + +int Function GetResourceType() + return ResourceType +EndFunction + +bool Function IsSabotaged() +; debug.trace(self + "IsSabotaged() returning " + sabotaged) + return sabotaged +EndFunction + +bool Function PromptPlayerSabotage() +; debug.trace(self + "PromptPlayerSabotage() asking player if he wants to sabotage") + if SabotageMessage.Show() == 1 +; debug.trace(self + "PromptPlayerSabotage() returning True") + return True + Else +; debug.trace(self + "PromptPlayerSabotage() returning False") + return False + EndIf +EndFunction + +bool Function PromptPlayerRepair() +; debug.trace(self + "PromptPlayerRepair() asking player if he wants to Repair") + if RepairMessage.Show() == 1 +; debug.trace(self + "PromptPlayerRepair() returning True") + return True + Else +; debug.trace(self + "PromptPlayerRepair() returning False") + return False + EndIf +EndFunction + + +Function Sabotage() +; debug.trace(self + "Sabotage() calling animation control functions") + DestroyResource() ;***animation control function defined in child script + +EndFunction + +Function Repair() +; debug.trace(self + "Repair() calling animation control functions") + + RepairResource() ;***animation control function defined in child script + + ClearDestruction() ;the purpose of this is to clear the destroyed flag in the destruction data so that guards guard it, and civil war missions fill with it in aliases. + +; debug.trace(self + "Repair() setting sabotaged to false") + readyForSabotage = false + sabotaged = False + +EndFunction + +Function Work() +; debug.trace(self + "Work() calling animation control functions") + WorkResource() ;***animation control function defined in child script + +EndFunction + +; ----------- + + +; -- ***Child scripts will extend these*** +;***Child scripts will extend these*** + +function ProcessAnimationEvent(string asEventName) +; debug.trace(self + "WARNING: ProcessAnimationEvent() is not defined by child script.", 2) +EndFunction + +function DestroyResource() +; debug.trace(self + "WARNING: DestroyResource() is not defined by child script.", 2) + endFunction + +function RepairResource() +; debug.trace(self + "WARNING: RepairResource() is not defined by child script.", 2) +endFunction + +function WorkResource() +; debug.trace(self + "WARNING: WorkResource() is not defined by child script.", 2) +EndFunction + +; -- ***Child scripts will extend these*** diff --git a/source/scripts/sayonhitbymagiceffectscript.psc b/source/scripts/sayonhitbymagiceffectscript.psc new file mode 100644 index 00000000..c942b457 --- /dev/null +++ b/source/scripts/sayonhitbymagiceffectscript.psc @@ -0,0 +1,43 @@ +Scriptname SayOnHitByMagicEffectScript extends ActiveMagicEffect +{Causes actor to say a line when hit by this spell} + +Topic Property TopicToSay Auto +{Which topic has the info the target should say?} + +Event OnEffectStart(Actor akTarget, Actor akCaster) + +; ; debug.trace(self + "OnEffectStart(" + akTarget + "," + akCaster + ")") + + If akTarget != Game.GetPlayer() + If akTarget.GetCurrentScene() == None + If GameDaysPassed.value > WICastNonHostileTimer.value + If AllowForTeammate == 0 + If akTarget.IsCommandedActor() == 0 || akTarget.IsPlayerTeammate() == 0 + If akTarget.IsInCombat() == 0 +; ; debug.trace(self + "OnEffectStart() will call Say(" + TopicToSay + ")") + WICastNonHostileTimer.SetValue(GameDaysPassed.GetValue() + 0.01) + akTarget.Say(TopicToSay) + ElseIf CombatTopicToSay != None + WICastNonHostileTimer.SetValue(GameDaysPassed.GetValue() + 0.01) + akTarget.Say(CombatTopicToSay) + EndIf + EndIf + ElseIf akTarget.IsPlayerTeammate() == 1 +; ; debug.trace(self + "OnEffectStart() will call Say(" + TopicToSay + ")") + WICastNonHostileTimer.SetValue(GameDaysPassed.GetValue() + 0.01) + akTarget.Say(TopicToSay) + EndIf + EndIf + EndIf + EndIf + +EndEvent + + +int Property AllowForTeammate = 0 Auto + +Topic Property CombatTopicToSay Auto + +GlobalVariable Property WICastNonHostileTimer Auto + +GlobalVariable Property GameDaysPassed Auto diff --git a/source/scripts/sethirelingrehire.psc b/source/scripts/sethirelingrehire.psc new file mode 100644 index 00000000..eacf81e9 --- /dev/null +++ b/source/scripts/sethirelingrehire.psc @@ -0,0 +1,42 @@ +Scriptname SetHirelingRehire extends Quest +{This script contains the function that triggers a 24-hour countdown, during which the player can re-hire the dismissed hireling for no cost.} + +GlobalVariable Property CanRehire Auto +int Property RehireWindow Auto +GlobalVariable Property GameDaysPassed Auto +GlobalVariable Property CanRehireBelrand Auto +GlobalVariable Property CanRehireErik Auto +GlobalVariable Property CanRehireJenassa Auto +GlobalVariable Property CanRehireMarcurio Auto +GlobalVariable Property CanRehireStenvar Auto +GlobalVariable Property CanRehireVorstag Auto +ActorBase Property Belrand Auto +ActorBase Property Erik Auto +ActorBase Property Jenassa Auto +ActorBase Property Marcurio Auto +ActorBase Property Stenvar Auto +ActorBase Property Vorstag Auto + +Function DismissHireling (Actorbase myFollower) + +If myFollower == Jenassa + CanRehireJenassa.SetValue(GameDaysPassed.value+1) + +elseif myFollower == Marcurio + CanRehireMarcurio.SetValue(GameDaysPassed.value+1) + +elseif myFollower == Stenvar + CanRehireStenvar.SetValue(GameDaysPassed.value+1) + +elseif myFollower == Vorstag + CanRehireVorstag.SetValue(GameDaysPassed.value+1) + +elseif myFollower == Belrand + CanRehireBelrand.SetValue(GameDaysPassed.value+1) + +elseif myFollower == Erik + CanRehireErik.SetValue(GameDaysPassed.value+1) + +endif + +endfunction diff --git a/source/scripts/shaderparticlegeometryscript.psc b/source/scripts/shaderparticlegeometryscript.psc new file mode 100644 index 00000000..7458bb37 --- /dev/null +++ b/source/scripts/shaderparticlegeometryscript.psc @@ -0,0 +1,88 @@ +scriptName ShaderParticleGeometryScript extends ActiveMagicEffect +{Generic ShaderParticleGeometry Data Script} + +import utility + +;======================================================================================; +; PROPERTIES / +;=============/ + +ShaderParticleGeometry property PSGD auto +{ShaderParticleGeometry applied at the start of the spell effect} + +float property FadeInTime = 1.0 auto +{Time it takes for the particles to fade in.} +float property FadeOutTime = 1.0 auto +{Time it takes for the particles to fade out.} +bool Property bUseDistanceCheck = False auto +{This will activate a system for checking the distance from a source so that we can remove the effect.} +Float Property fDistnceCheck = 1000.0 auto +{If we excede this distance, the effect will be removed.} +ObjectReference Property DistanceCheckerRef auto +{This is an optional property for and Object to check distance with, in empty, we place a marker at the player's location.} +activator property ActivatorRef auto +{The name of the Activator we will be placing.} + +;======================================================================================; +; EVENTS / +;=============/ + +bool bIsTooFar +bool bactive = false +actor player +ObjectReference DistanceCheckObject + +Event OnInit() + if bUseDistanceCheck + player = game.getplayer() + endif +EndEvent + +Event OnEffectStart(Actor Target, Actor Caster) + + If PSGD != None ;Do we have any data? + PSGD.remove(FadeOutTime) ; remove ShaderParticleGeometry + if caster == player + PSGD.apply(FadeInTime) ; apply ShaderParticleGeometry + endif + bactive = true + if bUseDistanceCheck + if DistanceCheckerRef + DistanceCheckObject = DistanceCheckerRef + Else + DistanceCheckObject = Caster.placeAtMe(ActivatorRef) + endif + RegisterForSingleUpdate(1.0) + endif + EndIf +EndEvent + +Event OnUpdate() + if bActive + if player.GetDistance(DistanceCheckObject) > fDistnceCheck + If bIsTooFar == false + PSGD.remove(FadeOutTime) + bIsTooFar = true + endif + Elseif bIsTooFar == true + PSGD.apply(FadeInTime) + bIsTooFar = false + endif + RegisterForSingleUpdate(1.0) + endif +EndEvent + +Event OnEffectFinish(Actor Target, Actor Caster) + bactive = False + If PSGD != None ;Do we have any data? + If bIsTooFar == false + PSGD.remove(FadeOutTime) ; remove ShaderParticleGeometry + else + PSGD.remove(0.1) + endif + EndIf + if ActivatorRef + DistanceCheckObject.disable() + DistanceCheckObject.delete() + endif +EndEvent diff --git a/source/scripts/silverswordscript.psc b/source/scripts/silverswordscript.psc new file mode 100644 index 00000000..03c8852f --- /dev/null +++ b/source/scripts/silverswordscript.psc @@ -0,0 +1,11 @@ +Scriptname SilverSwordScript extends ObjectReference + +Perk Property SilverPerk auto + +Event OnEquipped(Actor akActor) + akActor.AddPerk(SilverPerk) +EndEvent + +Event OnUnEquipped(Actor akActor) + akActor.RemovePerk(SilverPerk) +EndEvent \ No newline at end of file diff --git a/source/scripts/skyhavensconcescript.psc b/source/scripts/skyhavensconcescript.psc new file mode 100644 index 00000000..cec73bb3 --- /dev/null +++ b/source/scripts/skyhavensconcescript.psc @@ -0,0 +1,46 @@ +Scriptname SkyHavenSconceScript extends ObjectReference + +auto STATE WaitingToBeActivated + EVENT OnActivate (objectReference triggerRef) +; Debug.Trace("ACTIVATED") + TurnOnLight() + EndEvent + + + event OnLoad() + if EnableOnLoadMarker.IsEnabled() == 1 + ; make sure I'm on as well + TurnOnLight() + endif + endEvent + +EndState + +STATE done + ;done doing stuff +endSTATE + +function TurnOnLight() + ; get linked refs + ObjectReference mySconce = GetLinkedRef(SconceKeyword) + ObjectReference myLight = GetLinkedRef(LightKeyword) + if mySconce + GoToState("done") + mySconce.setAnimationVariableFloat("fToggleBlend", 1) + utility.wait(1) + myLight.Enable() + endif +endFunction + +Keyword Property SconceKeyword Auto +{the keyword for GetLinkedRef to the animating sconce object} + + +Keyword Property LightKeyword Auto +{the keyword for GetLinkedRef to the light object} + + + +ObjectReference Property EnableOnLoadMarker Auto +{when this marker is enabled, turn my light on OnLoad +(in case Delphine skipped any)} diff --git a/source/scripts/speartrap.psc b/source/scripts/speartrap.psc new file mode 100644 index 00000000..589db9d2 --- /dev/null +++ b/source/scripts/speartrap.psc @@ -0,0 +1,103 @@ +scriptName SpearTrap extends MovingTrap +; +; +;This is the script for the blade trap +;Activating the trap causes it to toggle on and off +;If activated while in the process of stopping, it should be able to handle that. +;================================================================ + +import debug +import utility + +;If Loop is true, it swings until activated again. +;If Loop is false, it swings once when activated. +bool restartLooping = false +bool finishedPlaying = false +float property initialDelay = 0.05 auto + +string property fireAnim = "Trigger01" auto +{firing animation, should not need to change} +string property fireEvent = "TrapStart" auto +{firing animation event, should not need to change} +string property resetAnim = "Open" auto +{reset animation, should not need to change} +string property resetEvent = "Opening" auto +{reset animation event, should not need to change} +string property startResetAnim = "Opened" auto +{reset animation event, should not need to change} + + + +;----------------------------------- + + + +Function fireTrap() + isFiring = True + ;Basic wind up and fire once checking + ;TRACE("fireTrap called") + ResolveLeveledDamage() + hitBase.goToState("CanHit") + if WindupSound + WindupSound.play( self as ObjectReference) ;play windup sound + endif + wait( initialDelay ) ;wait for windup + ;TRACE("Initial Delay complete") + + if (fireOnlyOnce == True) ;If this can be fired only once then disarm + trapDisarmed = True + endif + + ;TRACE("Looping =") + ;TRACE(Loop) + + ;Trap Guts + finishedPlaying = False + while !finishedPlaying && isLoaded + ;trace(self + "Firing trap: playanimation(" + fireAnim + ")") + ;trace(self + "Firing trap: waiting for event(" + fireEvent + ")") + PlayAnimationAndWait(fireAnim, fireEvent) + finishedPlaying = True + + if loop ;Reset Limiter + resetLimiter() + endif + wait(0.0) + endWhile + + if isLoaded + isFiring = False + hitBase.goToState("CannotHit") + goToState("Reset") + endif + ;trace(self + "Reset trap: playanimation(" + resetAnim + ")") + ;trace(self + "Reset trap: waiting for event(" + resetEvent + ")") + ;PlayAnimationAndWait(resetAnim, resetEvent) + +endFunction + +Function ResetLimiter() + finishedPlaying = False + ;TrapHitBase hitBase = (self as objectReference) as TrapHitBase + ;hitBase.goToState("CanHit") +EndFunction + +Event onReset() + self.reset() + goToState("Idle") +endEvent + +event onCellAttach() + isLoaded = TRUE + if isFiring == True + fireTrap() + endif +EndEvent + +event onCellDetach() +; debug.Trace(self + " has recieved onUnload event") + isLoaded = FALSE +endEvent + + + diff --git a/source/scripts/spiderwebanimationsscript.psc b/source/scripts/spiderwebanimationsscript.psc new file mode 100644 index 00000000..cce8d4ad --- /dev/null +++ b/source/scripts/spiderwebanimationsscript.psc @@ -0,0 +1,103 @@ +scriptName SpiderWebAnimationsSCRIPT extends ObjectReference + +{ +- This script randomly synchs two animations, one for the web and one for the actor in the web. +- The animations begin once the player enters the trigger and continue until either the player +leaves the trigger or is told to stop from somewhere else +} + +import debug +import utility + +bool inTrigger +bool doOnce + +bool property stopCondition auto hidden + +objectReference property myWeb auto +{The web} + +ObjectReference property webActor auto +{The actor in the web} + +Idle property idleWebThrashShort auto +{This is the idle for the actor to thrash.} + +Idle property idleWebThrashShort2 auto +{This is a second idle for the actor to thrash.} + +EffectShader Property WebbedFXS auto + +;***************************************** + +Function playWebAnimations(int iRand) + ;notification("Rand = " + iRand) + Actor myActor = webActor as Actor + if(iRand == 1 && !stopCondition) + myActor.playIdle( idleWebThrashShort ); + else + if(iRand == 2 && !stopCondition) + myActor.playIdle( idleWebThrashShort2 ) + endif + endif + + wait(5) + +endFunction + +;***************************************** + +Auto STATE Begin + Event onTriggerEnter (objectReference triggerRef) + Actor actorRef = triggerRef as Actor + if(actorRef == game.GetPlayer()) + inTrigger = true + if(stopCondition) + gotoState("done") + webActor.RemoveDependentAnimatedObjectReference(myWeb) + else + RegisterForSingleUpdate(0.5) + endif + endif + endEvent + + Event onTriggerLeave (objectReference triggerRef) + Actor actorRef = triggerRef as Actor + if(actorRef == game.GetPlayer()) + inTrigger = false + endif + endEvent +endState + +;************************************ + +Event onUpdate() + bool beginAnimations = true + ;UnRegisterForUpdate() + while(inTrigger && !stopCondition) + ;stopCondition is set to true by the WebDestructibleScript on the webFX reference + int rand = RandomInt(1,2) + Actor myActor = webActor as Actor + myActor.setav("Variable03", rand) + playWebAnimations(rand) + wait(5) + endWhile +endEvent + +;***************************************** + +STATE done + ;do nothing +endState + +;***************************************** + +Event onLoad() + if(!doOnce) + WebbedFXS.Play(webActor) + webActor.AddDependentAnimatedObjectReference( myWeb ) + doOnce = true + endif +endEvent + +;***************************************** \ No newline at end of file diff --git a/source/scripts/spriggancallanimalsaoe.psc b/source/scripts/spriggancallanimalsaoe.psc new file mode 100644 index 00000000..d7c6f02b --- /dev/null +++ b/source/scripts/spriggancallanimalsaoe.psc @@ -0,0 +1,55 @@ +scriptname sprigganCallAnimalsAOE extends activeMagicEffect +{Prototype for an ability where SPriggans call helper animals} + +faction property creatureFaction auto +faction property sprigganFaction auto + +actor caster +objectReference casterRef + +float myConfidence +float myAggression + +bool property bDebug = FALSE auto + +EVENT OnEffectStart(Actor akTarget, Actor akCaster) + caster = akCaster + casterRef = (caster as ObjectReference) + + if bDebug +; debug.trace("TEST: applied Spriggan AoE to :"+akTarget) +; debug.trace("TEST: AoE was cast by: "+casterRef) +; debug.trace("TEST: Enemy of Spriggan: "+caster.getCombatTarget()) + endif + + if akTarget.isInFaction(creatureFaction) == TRUE && !akTarget.isDead() + + ; save my conf/aggro values so they can be reset + myConfidence = akTarget.getActorValue("confidence") + myAggression = akTarget.getActorValue("aggression") + + ; make my enemies the spriggan's enemies temporarily + akTarget.addToFaction(sprigganFaction) + + ; if the spriggan caster has a combat target (she should) then I will beeline to attack it! + if caster.getCombatTarget() + akTarget.startCombat(caster.getCombatTarget()) + endif + + ; make this animal very aggressive/confident for the duration of the spell + akTarget.setActorValue("confidence", 4) + akTarget.setActorValue("aggression", 1) + + endif + +endEVENT + +EVENT OnEffectFinish(Actor akTarget, Actor akCaster) + +; debug.trace("TEST: Released from Spriggan Enthrallment: "+self) + + akTarget.setActorValue("confidence", myConfidence) + akTarget.setActorValue("aggression", myAggression) + akTarget.RemoveFromFaction(sprigganFaction) + akTarget.evaluatePackage() +endEVENT diff --git a/source/scripts/sprigganswarmactorscript.psc b/source/scripts/sprigganswarmactorscript.psc new file mode 100644 index 00000000..c426e795 --- /dev/null +++ b/source/scripts/sprigganswarmactorscript.psc @@ -0,0 +1,52 @@ +Scriptname SprigganSwarmActorSCRIPT extends ActiveMagicEffect conditional +{Attaches and manages witchlights's fx} +;======================================================================================; +; IMPORTS / +;=============/ +import utility +import form +import game +;======================================================================================; +; PROPERTIES / +;=============/ +VisualEffect Property SprigganSwarmFXAttachEffect Auto +objectReference property mySprigganSwarm auto conditional hidden +actorBase property SprigganSwarmBase auto + +;======================================================================================; +; VARIABLES / +;=============/ +ObjectReference selfRef + +;======================================================================================; +; EVENTS / +;=============/ + + EVENT OnEffectStart(Actor Target, Actor Caster) + + + selfRef = caster + selfRef.RegisterForSingleUpdate(0.25) + int i = 10 ; recursion limiter for 3dLoaded check + while selfRef.is3dLoaded() == FALSE + ; wait for onLoad() to complete + ; too costly ??? + if i >= 10 +; debug.trace("Recursion of limit ("+i+") hit by: "+self) + return + else + i+=1 +; debug.trace("While() recursion ("+i+")") + endif + endWhile + ; only attack FX once the3D is loaded + SprigganSwarmFXAttachEffect.Play(selfRef, -1) + + ENDEVENT + + + EVENT onDeath(actor myKiller) + + SprigganSwarmFXAttachEffect.Stop(selfRef) + + ENDEVENT \ No newline at end of file diff --git a/source/scripts/summontargetfxactivatorscript.psc b/source/scripts/summontargetfxactivatorscript.psc new file mode 100644 index 00000000..86149254 --- /dev/null +++ b/source/scripts/summontargetfxactivatorscript.psc @@ -0,0 +1,8 @@ +scriptName SummonTargetFXActivatorScript extends ObjectReference + +Event OnLoad() + Utility.Wait(5) + Self.Disable() + Utility.Wait(1) + Self.Delete() +EndEvent diff --git a/source/scripts/trapbase.psc b/source/scripts/trapbase.psc new file mode 100644 index 00000000..56e0269c --- /dev/null +++ b/source/scripts/trapbase.psc @@ -0,0 +1,246 @@ +scriptName TrapBase extends objectReference +; +;This is the base trap script and handles what the trap is told by the trigger +;Any Trap should be usable with any trigger +;Trap params are on the trap (damage, timing, etc) +;Activation params are on the trigger, toggle, number of times it can be triggered, etc. +;Individual traps will be extended from this framework + + ;Trigger Types for quick reference + ;0 = Single - fire the trap once do one time + ;1 = Hold - on entry turn on, on exit turn off + ;2 = Toggle - on entry or use toggle trap state + ;3 = Turn On - on entry or use turn on trap + ;4 = Turn Off - on entry or use turn off trap + +;================================================================ + + + +bool property init auto hidden ; This should not be set by the user +bool property trapDisarmed auto hidden ; This should not be set by the user +bool property loop auto hidden ; This should not be set by the user +objectReference property lastActivateRef auto hidden + +bool Property fireOnlyOnce auto ;This should be set by the user +sound property WindupSound auto ;Played when winding up or releasing trap +;sound Property TrapHitSound auto ;Played when the trap hits something +;int property trapPushBack auto ;push back impulse provided by the trap + +bool property overrideLoop = False auto hidden + +int Property TrapLevel = 1 auto +{Used to determine the difficulty of the trap, currently only tied to damage + 0 = Easy + 1 = Medium (DEFAULT) + 2 = Hard + 3 = VeryHard} + +int Property damage auto hidden + +TrapHitBase property hitBase auto hidden + +Function initialize() ; Placeholder - replaced with trap specific function +endFunction + +Function fireTrap() ; Placeholder - replaced with trap specific function + ResolveLeveledDamage() +endFunction + +Function resetLimiter() ; Placeholder - replaced with trap specific function +endFunction + +;================================================================ + + +auto State Idle + + event onActivate (objectReference activateRef) +; ;debug.TRACE("Idle trigger") + lastActivateRef = activateRef + if (trapDisarmed == False) + if init == False ;determine if we should initialize + initialize() + init = True + endif + + TrapTriggerBase TriggerRef ;TriggerRef will always be a TrapTriggerBase + TriggerRef = activateRef as TrapTriggerBase ;Set TriggerRef to our activateRef +; ;debug.Trace("Type = " + TriggerRef.Type) + + if TriggerRef + ;TRACE("Type =") + ;TRACE(TriggerRef.Type) + if (TriggerRef.Type == 0) ;if Type = 0 Single activate + GoToState ( "DoOnce" ) ;DoOnce Trigger Type + ResetLimiter() + FireTrap() + elseif (TriggerRef.Type == 1) ;Hold Trigger Type + GoToState ( "Hold" ) + ResetLimiter() + Loop = TRUE + FireTrap() + elseif (TriggerRef.Type >1 && TriggerRef.Type < 4) ;Most Trigger Types use On + GoToState ( "On" ) + ResetLimiter() + Loop = TRUE + FireTrap() + endif + else + GoToState ( "DoOnce" ) ;DoOnce Trigger Type + ResetLimiter() + FireTrap() + endif + endif + endevent + +endstate + +State DoOnce ;Type Do Once + + Event OnActivate( objectReference activateRef ) +; ;debug.TRACE(self + "Do Once trigger") + lastActivateRef = activateRef + if (trapDisarmed == FALSE) + TrapTriggerBase TriggerRef ;TriggerRef will always be a TrapTriggerBase + TriggerRef = activateRef as TrapTriggerBase ;Set TriggerRef to our activateRef + +; ;debug.Trace("Type = " + TriggerRef.Type) + + If TriggerRef + if (TriggerRef.Type == 0) ;Type Do Once + resetLimiter() + endif + + if (TriggerRef.Type == 1) ;Type Hold + GoToState("Hold") + resetLimiter() + Loop = TRUE + endif + + if (TriggerRef.Type >1 && TriggerRef.Type < 4) ;Most Trigger Types use On + GoToState ( "On" ) + ResetLimiter() + Loop = TRUE + endif + + if (TriggerRef.Type == 4) ;Type Hold + Loop = FALSE + GoToState("Reset") + endif + else + + endif + endif + + EndEvent + +endstate + +State Reset + + Event OnBeginState() + overrideLoop = True + GoToState ( "Idle" ) + hitBase = (self as objectReference) as TrapHitBase + if hitbase + hitBase.goToState("CannotHit") + endif + endEvent + + Event OnActivate( objectReference activateRef ) + lastActivateRef = activateRef + EndEvent + +endState + +State On + + event onActivate (objectReference activateRef) +; ;debug.TRACE(self + "On trigger") + lastActivateRef = activateRef + if (trapDisarmed == FALSE) + TrapTriggerBase TriggerRef ;TriggerRef will always be a TrapTriggerBase + TriggerRef = activateRef as TrapTriggerBase ;Set TriggerRef to our activateRef + +; ;debug.Trace("Type = " + TriggerRef.Type) + + if TriggerRef + ;/ + if (TriggerRef.Type == 1) ;Type Hold + GoToState("Hold") + resetLimiter() + Loop = TRUE + endif + /; + + if (TriggerRef.Type == 4) ;if Type = 4 Turn Off + GoToState ( "Reset" ) + Loop = FALSE + overrideLoop = True + endif + + if (TriggerRef.Type == 2) ;if Type = 2 Toggle + GoToState ( "Reset" ) + Loop = FALSE + overrideLoop = True + endif + endif + endif + + endevent + +endstate + +State Hold ;Hold overrides all other states ***This is kind of a depricated state *** + + event onActivate (objectReference activateRef) +; ;debug.TRACE(self + "Hold trigger") + lastActivateRef = activateRef + if (trapDisarmed == FALSE) + TrapTriggerBase TriggerRef ;TriggerRef will always be a TrapTriggerBase + TriggerRef = activateRef as TrapTriggerBase ;Set TriggerRef to our activateRef + +; ;debug.Trace("Type = " + TriggerRef.Type) + + if TriggerRef + if (TriggerRef.Type == 1) ;if Type = 1 Turn Off + GoToState ( "On" ) + Loop = FALSE + endif + + if (TriggerRef.Type == 2) ;Type Hold + Loop = FALSE + GoToState("Reset") + endif + + if (TriggerRef.Type == 3) ;if Type = 1 Turn Off + GoToState ( "On" ) + Loop = FALSE + endif + + if (TriggerRef.Type == 4) ;Type Hold + Loop = FALSE + GoToState("Reset") + endif + endif + endif + endEvent + +endstate + +State Disarmed + +endState + +;-------------------------------------- +Function ResolveLeveledDamage () ;placeholder function, declared in children + hitBase = (self as objectReference) as TrapHitBase + hitBase.damage = 0 ;In child functions this will be defined +EndFunction + + + + + + diff --git a/source/scripts/trapbear.psc b/source/scripts/trapbear.psc new file mode 100644 index 00000000..2e04b679 --- /dev/null +++ b/source/scripts/trapbear.psc @@ -0,0 +1,164 @@ +scriptName TrapBear extends objectReference +; +; +;========================================== + +TrapHitBase hitBase +bool property StartOpen = True Auto +perk property LightFoot auto +bool property checkForLightFootPerk = true Auto +{default == true} +globalVariable property LightFootTriggerPercent auto + +Event onReset() + goToState("Closed") + self.reset() +endEvent + + +event onLoad() + hitBase = (self as objectReference) as TrapHitBase + ResolveLeveledDamage() + if StartOpen + playAnimation("StartOpen") + goToState("Open") + endif +endEvent + +auto state Closed + Event OnBeginState() +; debug.Trace(self + " has entered state Closed") + endEvent + + event OnTriggerEnter(objectReference TriggerRef) +; debug.Trace(self + " has been entered by " + TriggerRef) +; debug.Trace(self + " is in state Closed") + endEvent + + event OnActivate(objectReference TriggerRef) +; debug.Trace(self + " has been activated by " + TriggerRef) +; debug.Trace(self + " is in state Closed") + playAnimationAndWait("Reset01","Trans02") + goToState("Open") + endEvent + +endState + +state Open + Event OnBeginState() +; debug.Trace(self + " has entered state Open") + endEvent + + event OnTriggerEnter(objectReference TriggerRef) + if checkPerks(TriggerRef) +; debug.Trace(self + " has been entered by " + TriggerRef) +; debug.Trace(self + " is in state Open") + playAnimation("Trigger01") + hitBase.goToState("CanHit") + GoToState("Busy") + WaitForAnimationEvent("Trans01") + hitBase.goToState("CannotHit") + GoToState("Closed") + endif + endEvent + + event OnActivate(objectReference TriggerRef) +; debug.Trace(self + " has been activated by " + TriggerRef) +; debug.Trace(self + " is in state Open") + GoToState("Busy") + hitBase.goToState("CannotHit") + playAnimationAndWait("Trigger01","Trans01") + goToState("Closed") + endEvent +endState + +State Busy ;Dummy state to prevent interaction while animating + Event OnBeginState() +; debug.Trace(self + " has entered state Open") + endEvent +EndState + +event OnTriggerEnter(objectReference TriggerRef) +; debug.Trace(self + " has been entered by " + TriggerRef) +; debug.Trace(self + " default onEnter") +endEvent + +event OnActivate(objectReference TriggerRef) +; debug.Trace(self + " has been activated by " + TriggerRef) +; debug.Trace(self + " default onTrigger") +endEvent + +Bool function checkPerks(objectReference triggerRef) + if checkForLightFootPerk +; ;debug.Trace(self + " is checking if " + triggerRef + " has LightFoot Perk") + if (triggerRef as actor).hasPerk(LightFoot) +; ;debug.Trace(self + " has found that " + triggerRef + " has LightFoot Perk") + if utility.randomFloat(0.0,100.00) <= LightFootTriggerPercent.getValue() +; ;debug.Trace(self + " is returning false due to failed lightfoot roll") + return False + else +; ;debug.Trace(self + " is returning true due to successful lightfoot roll") + return True + endif + Else +; debug.Trace(self + " has found that " + triggerRef + " doesn't have the LightFoot Perk") + Return True + EndIf + else + return True + endif +endFunction + +;========================================================== +int property LvlThreshold1 auto +int property LvlDamage1 auto +int property LvlThreshold2 auto +int property LvlDamage2 auto +int property LvlThreshold3 auto +int property LvlDamage3 auto +int property LvlThreshold4 auto +int property LvlDamage4 auto +int property LvlThreshold5 auto +int property LvlDamage5 auto +int property LvlDamage6 auto +int property TrapLevel = 2 auto + +Function ResolveLeveledDamage() + int damageLevel + int damage + damageLevel = CalculateEncounterLevel(TrapLevel) + + damage = LvlDamage1 + + if (damageLevel > LvlThreshold1 && damageLevel <= LvlThreshold2) + damage = LvlDamage2 + ;Trace("damage threshold =") + ;Trace("2") + endif + if (damageLevel > LvlThreshold2 && damageLevel <= LvlThreshold3) + damage = LvlDamage3 + ;Trace("damage threshold =") + ;Trace("3") + endif + if (damageLevel > LvlThreshold3 && damageLevel <= LvlThreshold4) + damage = LvlDamage4 + ;Trace("damage threshold =") + ;Trace("4") + endif + if (damageLevel > LvlThreshold4 && damageLevel <= LvlThreshold5) + damage = LvlDamage5 + ;Trace("damage threshold =") + ;Trace("5") + endif + if (damageLevel > LvlThreshold5) + damage = LvlDamage6 + ;Trace("damage threshold =") + ;Trace("6") + endif + + ;Trace("damage =") + ;Trace(damage) + + ;return damage + hitBase.damage = damage +EndFunction \ No newline at end of file diff --git a/source/scripts/trapdweballista.psc b/source/scripts/trapdweballista.psc new file mode 100644 index 00000000..180c7280 --- /dev/null +++ b/source/scripts/trapdweballista.psc @@ -0,0 +1,204 @@ +scriptName TrapDweBallista extends TrapBase +; +;Dart Trap extending TrapBase +;integrated with the TrapTriggerBase +; +;================================================================ + +import debug +import utility +import custom + +int property shotCount = 3 auto +{This property track the ammo that the ballista has, and starts with} +;int numShots = 20 ;might want to make this a property +float fireRate = 0.1 +float property initialDelay = 0.0 auto +weapon property ballistaWeaponM auto +weapon property ballistaWeaponL auto +weapon property ballistaWeaponR auto +bool property fireAllShots = True auto +{if this is true all three shots will be fired at once} + +bool property isFiring auto hidden +bool property isLoaded auto hidden +bool property shotFired = false auto hidden +bool property weaponResolved = false auto hidden + +Function initialize() + +endFunction + + +Function ResetLimiter() + shotFired = false ;shotCount is scoped outside of the OnActivate blocks. This will reset scopecount to 0, extending the firing time. +EndFunction + + +Function fireTrap() + if !TrapDisarmed + isFiring = True + objectReference TrapSelf = self as objectReference + if !weaponResolved + ResolveLeveledWeapon() + endif + while !weaponResolved ;Do not fire till weapon is resolved + endWhile + ;TRACE("fireTrap called") + WindupSound.play( self as ObjectReference) ;play windup sound + wait( initialDelay ) ;wait for windup + ; if (fireOnlyOnce == True) ;If this can be fired only once then disarm + ; trapDisarmed = True + ; endif + + while(shotcount > 0) && !shotfired && isLoaded + if fireAllShots + playAnimation("TriggerAll") ;fire all + ballistaWeaponM.fire( TrapSelf, ballistaAmmo ) ;fire 01 + ballistaWeaponL.fire( TrapSelf, ballistaAmmo ) ;fire 02 + ballistaWeaponR.fire( TrapSelf, ballistaAmmo ) ;fire 03 + + shotcount -= 3 + WaitForAnimationEvent("FTransAll") + ;playAnimationAndWait("ResetAll","RTransAll") ;reset anim all + else + if shotCount == 3 + playAnimation("Trigger01") ;fire anim 01 + ballistaWeaponM.fire( TrapSelf, ballistaAmmo ) ;fire 01 + shotcount -= 1 + WaitForAnimationEvent("FTrans01") + playAnimationAndWait("Reset01","RTrans01") ;reset anim 01 + elseIf ShotCount == 2 + playAnimation("Trigger02") ;fire anim 02 + ballistaWeaponL.fire( TrapSelf, ballistaAmmo ) ;fire 02 + shotcount -= 1 + WaitForAnimationEvent("FTrans02") + playAnimationAndWait("Reset02","RTrans02") ;reset anim 02 + elseIf ShotCount == 1 + playAnimation("Trigger03") ;fire anim 03 + ballistaWeaponR.fire( TrapSelf, ballistaAmmo ) ;fire 03 + shotcount -= 1 + WaitForAnimationEvent("FTrans03") + ;playAnimationAndWait("Reset03","RTrans03") ;reset anim 03 + endIf + endIf + shotFired = True + if (loop == TRUE) ;Reset Limiter + resetLimiter() + endif + endWhile + + if isLoaded + isFiring = false + ;playAnimation("idle") + goToState("Reset") + endif + + endif + +endFunction + +State Reset + + Event OnBeginState() + ;TRACE("State Reset") + if shotcount > 0 + ;shotCount = 3 + GoToState ( "Idle" ) + Else + TrapDisarmed = True + GoToState ("Disabled") + endif + + endEvent + + Event OnActivate( objectReference activateRef ) + ;TRACE("Reset trigger") + EndEvent + +endState + +;----------------------------------------------- + +int property LvlThreshold1 auto +int property LvlThreshold2 auto +int property LvlThreshold3 auto +int property LvlThreshold4 auto +int property LvlThreshold5 auto +ammo property ballistaAmmo auto +ammo property TrapDweBallistaBoltAmmo01 auto +ammo property TrapDweBallistaBoltAmmo02 auto +ammo property TrapDweBallistaBoltAmmo03 auto +ammo property TrapDweBallistaBoltAmmo04 auto +ammo property TrapDweBallistaBoltAmmo05 auto +ammo property TrapDweBallistaBoltAmmo06 auto + +Function ResolveLeveledWeapon () + ;Trace("ResolveLeveledWeapon") + int damageLevel + damageLevel = CalculateEncounterLevel(TrapLevel) + + ; weapon lvlWeaponM = LvlWeaponM1 + ; weapon lvlWeaponL = LvlWeaponL1 + ; weapon lvlWeaponR = LvlWeaponR1 + Ammo LvlAmmo = TrapDweBallistaBoltAmmo01 + + if (damageLevel > LvlThreshold1 && damageLevel <= LvlThreshold2) + ; lvlWeaponM = LvlWeaponM2 + ; lvlWeaponL = LvlWeaponL2 + ; lvlWeaponR = LvlWeaponR2 + LvlAmmo = TrapDweBallistaBoltAmmo02 + ;Trace("damage threshold =") + ;Trace("2") + endif + if (damageLevel > LvlThreshold2 && damageLevel <= LvlThreshold3) + ;lvlWeaponM = LvlWeapon3 + LvlAmmo = TrapDweBallistaBoltAmmo03 + ;Trace("damage threshold =") + ;Trace("3") + endif + if (damageLevel > LvlThreshold3 && damageLevel <= LvlThreshold4) + ;lvlWeaponM = LvlWeapon4 + LvlAmmo = TrapDweBallistaBoltAmmo04 + ;Trace("damage threshold =") + ;Trace("4") + endif + if (damageLevel > LvlThreshold4 && damageLevel <= LvlThreshold5) + ;lvlWeaponM = LvlWeapon5 + LvlAmmo = TrapDweBallistaBoltAmmo05 + ;Trace("damage threshold =") + ;Trace("5") + endif + if (damageLevel > LvlThreshold5) + ;lvlWeaponM = LvlWeapon6 + LvlAmmo = TrapDweBallistaBoltAmmo06 + ;Trace("damage threshold =") + ;Trace("6") + endif + + ; ballistaWeaponM = lvlWeaponM + ; ballistaWeaponL = lvlWeaponL + ; ballistaWeaponR = lvlWeaponR + BallistaAmmo = LvlAmmo + weaponResolved = True +EndFunction + +event onLoad() + isLoaded = TRUE + if isFiring == True + fireTrap() + endif + if shotCount == 3 + playAnimationAndWait("Reset03","RTrans03") ;reset anim 01 + elseIf ShotCount == 2 + playAnimationAndWait("Reset01","RTrans01") ;reset anim 02 + elseIf ShotCount == 1 + playAnimationAndWait("Reset02","RTrans02") ;reset anim 02 + endIf +EndEvent + +event onUnload() +; debug.Trace(self + " has recieved onUnload event") + isLoaded = FALSE +endEvent + diff --git a/source/scripts/trapdweflamepillar.psc b/source/scripts/trapdweflamepillar.psc new file mode 100644 index 00000000..0e6bbeea --- /dev/null +++ b/source/scripts/trapdweflamepillar.psc @@ -0,0 +1,110 @@ +scriptName TrapDweFlamePillar extends MovingTrap +; +; +;This is the script for the blade trap +;Activating the trap causes it to toggle on and off +;If activated while in the process of stopping, it should be able to handle that. +;================================================================ + + + +import debug +import utility + +;If Loop is true, it swings until activated again. +;If Loop is false, it swings once when activated. +bool restartLooping = false +bool finishedPlaying = false +float property initialDelay = 0.25 auto +float property rotationSpeed = 1.0 auto +Bool property CounterClockwise = FALSE auto +{if true this will turn counter-clockwise + default == false} + +bool property hasPlayedAttackAnimOnce = false auto hidden + + +event onLoad() + float CV = (rotationSpeed * getAnimationVariableFloat("CV")) + float CCV = (rotationSpeed * getAnimationVariableFloat("CCV")) + SetAnimationVariableFloat("CV", CV) + SetAnimationVariableFloat("CCV", CCV) + ;hitBase = (self as objectReference) as TrapDweFlamePillarHit + +endEvent + + +;----------------------------------- + +Function fireTrap() + TrapDweFlamePillarHit myHitScript + myHitScript = (self as objectReference) as TrapDweFlamePillarHit + + isFiring = True + if myHitScript + myHitScript.goToState("CanHitLocal") + else +; debug.Trace(self + ": myHitScript = " + myHitScript) + endif + objectReference TrapSelf = self as objectReference + + if WindupSound + WindupSound.play( self as ObjectReference) ;play windup sound + endif + ;ResolveLeveledWeapon() + hasPlayedAttackAnimOnce = False + wait( initialDelay ) ;wait for windup + ;TRACE("Initial Delay complete") + + if (fireOnlyOnce == True) ;If this can be fired only once then disarm + trapDisarmed = True + endif + + ;TRACE("Looping =") + ;TRACE(Loop) + + ;Trap Guts + + while(finishedPlaying == False && isLoaded == true) + ;TRACE("playing anim Single") + isFiring = True + if (hasPlayedAttackAnimOnce == FALSE) + hasPlayedAttackAnimOnce = TRUE + if CounterClockwise + PlayAnimationAndWait("Trigger01","Trans01") + else + PlayAnimationAndWait("Trigger01","Trans01") + endif +; debug.Trace(self + " has recieved event " + "Trans01") + + Else + wait(0.5) + endif + + finishedPlaying = True + + if (loop == TRUE) ;Reset Limiter + resetLimiter() + endif + endWhile + + ;self.InterruptCast() + myHitScript.goToState("CannotHit") + +; debug.Trace(self + " has exited looping") + if isLoaded + isFiring = false + PlayAnimationAndWait( "Reset01", "Trans02" ) + goToState("Reset") + endif + + + +endFunction + +Function ResetLimiter() + finishedPlaying = False +EndFunction + + + diff --git a/source/scripts/trapdweflamepillarhit.psc b/source/scripts/trapdweflamepillarhit.psc new file mode 100644 index 00000000..781524f6 --- /dev/null +++ b/source/scripts/trapdweflamepillarhit.psc @@ -0,0 +1,143 @@ +scriptName TrapDweFlamePillarHit extends trapHitBase +; +; +; +;========================================= + +import utility + +keyword property flameKeyword auto + +explosion property placedExplosion auto hidden +bool property weaponResolved = false auto hidden +int Property TrapLevel = 1 auto +{Used to determine the difficulty of the trap, currently only tied to damage + 0 = Easy + 1 = Medium (DEFAULT) + 2 = Hard + 3 = VeryHard} + +;================================================================ + +state CanHitLocal + event onBeginState() +; debug.Trace(self + ": has entered CanHitState") + if !weaponResolved + ResolveLeveledExplosion () + endif + endEvent + + + event OnTrapHitStart(ObjectReference triggerRef, float afXVel, float afYVel, float afZVel, float afXPos, float afYPos, float afZPos, int aeMaterial, bool abInitialHit, int aeMotionType) +; debug.Trace(self + " has hit " + triggerRef) + actor myTarget + myTarget = triggerRef as actor + + if !myTarget.hasSpell(ghostAbility) + ;if !myTarget.HasMagicEffectWithKeyword(flameKeyword) +; debug.Trace(self + " has applied gas to " + triggerRef) + ;(triggerRef as actor).addSpell(gasSpell01) + triggerRef.placeAtMe(placedExplosion) + ;endif + if rumble + game.ShakeController(rumbleAmount, rumbleAmount, rumbleDuration) + EndIf + if cameraShake + game.ShakeCamera(afStrength = cameraShakeAmount) + endif + endif + endEvent + + ;/ + event OnTrapHit(ObjectReference triggerRef, float afXVel, float afYVel, float afZVel, float afXPos, float afYPos, float afZPos, int aeMaterial, bool abInitialHit, int aeMotionType) +; debug.Trace(self + " has hit " + triggerRef) + actor myTarget + myTarget = triggerRef as actor + + if !myTarget.hasSpell(ghostAbility) + ;if !myTarget.HasMagicEffectWithKeyword(flameKeyword) +; debug.Trace(self + " has applied gas to " + triggerRef) + ;(triggerRef as actor).addSpell(gasSpell01) + triggerRef.placeAtMe(placedExplosion) + ;endif + if rumble + game.ShakeController(rumbleAmount, rumbleAmount, rumbleDuration) + EndIf + if cameraShake + game.ShakeCamera(afStrength = cameraShakeAmount) + endif + endif + endEvent + /; +endState + +event onCellAttach() + if !weaponResolved + ResolveLeveledExplosion () + endif +endEvent + + +;================================================================ + +int property LvlThreshold1 auto +int property LvlThreshold2 auto +int property LvlThreshold3 auto +int property LvlThreshold4 auto +int property LvlThreshold5 auto +Explosion property TrapDweFlamePillarExplosion01 auto +Explosion property TrapDweFlamePillarExplosion02 auto +Explosion property TrapDweFlamePillarExplosion03 auto +Explosion property TrapDweFlamePillarExplosion04 auto +Explosion property TrapDweFlamePillarExplosion05 auto +Explosion property TrapDweFlamePillarExplosion06 auto + +Function ResolveLeveledExplosion () + ;Trace("ResolveLeveledWeapon") + int damageLevel + damageLevel = CalculateEncounterLevel(TrapLevel) + + ; weapon lvlWeaponM = LvlWeaponM1 + ; weapon lvlWeaponL = LvlWeaponL1 + ; weapon lvlWeaponR = LvlWeaponR1 + explosion LvlExplosion = TrapDweFlamePillarExplosion01 + + if (damageLevel > LvlThreshold1 && damageLevel <= LvlThreshold2) + ; lvlWeaponM = LvlWeaponM2 + ; lvlWeaponL = LvlWeaponL2 + ; lvlWeaponR = LvlWeaponR2 + LvlExplosion = TrapDweFlamePillarExplosion02 + ;Trace("damage threshold =") + ;Trace("2") + endif + if (damageLevel > LvlThreshold2 && damageLevel <= LvlThreshold3) + ;lvlWeaponM = LvlWeapon3 + LvlExplosion = TrapDweFlamePillarExplosion03 + ;Trace("damage threshold =") + ;Trace("3") + endif + if (damageLevel > LvlThreshold3 && damageLevel <= LvlThreshold4) + ;lvlWeaponM = LvlWeapon4 + LvlExplosion = TrapDweFlamePillarExplosion04 + ;Trace("damage threshold =") + ;Trace("4") + endif + if (damageLevel > LvlThreshold4 && damageLevel <= LvlThreshold5) + ;lvlWeaponM = LvlWeapon5 + LvlExplosion = TrapDweFlamePillarExplosion05 + ;Trace("damage threshold =") + ;Trace("5") + endif + if (damageLevel > LvlThreshold5) + ;lvlWeaponM = LvlWeapon6 + LvlExplosion = TrapDweFlamePillarExplosion06 + ;Trace("damage threshold =") + ;Trace("6") + endif + + ; ballistaWeaponM = lvlWeaponM + ; ballistaWeaponL = lvlWeaponL + ; ballistaWeaponR = lvlWeaponR + placedExplosion = LvlExplosion + weaponResolved = True +EndFunction diff --git a/source/scripts/trapdwepiston.psc b/source/scripts/trapdwepiston.psc new file mode 100644 index 00000000..e0bbf7e8 --- /dev/null +++ b/source/scripts/trapdwepiston.psc @@ -0,0 +1,178 @@ +scriptName TrapDwePiston extends MovingTrap +; +; +;This is the script for the blade trap +;Activating the trap causes it to toggle on and off +;If activated while in the process of stopping, it should be able to handle that. +;================================================================ + +import debug +import utility + +;If Loop is true, it swings until activated again. +;If Loop is false, it swings once when activated. +bool restartLooping = false +bool finishedPlaying = false +bool hasPlayedAttackAnimOnce = FALSE +float property initialDelay = 0.25 auto + +string property fireAnim = "Up" auto +{firing animation, should not need to change} +string property fireEvent = "TransUp" auto +{firing animation event, should not need to change} +string property resetAnim = "Down" auto +{reset animation, should not need to change} +string property resetEvent = "TransDown" auto +{reset animation event, should not need to change} +string property startSwungAnim = "StartUp" auto +{anim event to start already swung} + +bool property startSwung = false auto hidden +{set to true to start swung} + + +;----------------------------------- + + + +EVENT OnCellAttach() + isLoaded = TRUE + + if isFiring || startSwung + if startSwung + ;isFiring == True + loop = True + goToState("On") + endif + fireTrap() + endif +endEVENT + +Function fireTrap() + + ;Basic wind up and fire once checking + ;TRACE("fireTrap called") + isFiring = True + + if !startSwung + if WindupSound + WindupSound.play( self as ObjectReference) ;play windup sound + endif + wait( initialDelay ) ;wait for windup + endif + hasPlayedAttackAnimOnce = FALSE + ;TRACE("Initial Delay complete") + + if (fireOnlyOnce == True) ;If this can be fired only once then disarm + trapDisarmed = True + endif + + ;TRACE("Looping =") + ;TRACE(Loop) + + ;Trap Guts + finishedPlaying = False + while !finishedPlaying && isLoaded + ;trace(self + "Firing trap: playanimation(" + fireAnim + ")") + ;trace(self + "Firing trap: waiting for event(" + fireEvent + ")") + if !hasPlayedAttackAnimOnce + if !startSwung + PlayAnimationAndWait(fireAnim, fireEvent) +; ;debug.Trace(self + "has finished anim once") + hasPlayedAttackAnimOnce = TRUE + else + startSwung = False + playAnimation(startSwungAnim) + hasPlayedAttackAnimOnce = TRUE + endif + Else + wait(0.5) + endif + finishedPlaying = True + + if loop ;Reset Limiter +; ;debug.Trace(self + "is looping because loop = " + loop) + resetLimiter() + endif + endWhile + + if isLoaded + isFiring = false + PlayAnimationAndWait(resetAnim, resetEvent) + goToState("Reset") + endif + ;trace(self + "Reset trap: playanimation(" + resetAnim + ")") + ;trace(self + "Reset trap: waiting for event(" + resetEvent + ")") + + +endFunction + + +;/ +Function fireTrap() + + + isFiring = True + if hitbase + hitBase.goToState("CanHit") + endif + if windupSound + WindupSound.play( self as ObjectReference) ;play windup sound + endif + ResolveLeveledDamage() + wait( initialDelay ) ;wait for windup + hasPlayedAttackAnimOnce = FALSE + ;TRACE("Initial Delay complete") + + if (fireOnlyOnce == True) ;If this can be fired only once then disarm + trapDisarmed = True + endif + + ;TRACE("Looping =") + ;TRACE(Loop) + + ;Trap Guts + while(finishedPlaying == False && isLoaded == true) + ;trace(self + "Firing trap: playanimation(" + fireAnim + ")") + ;trace(self + "Firing trap: waiting for event(" + fireEvent + ")") + if (hasPlayedAttackAnimOnce == FALSE) + PlayAnimationAndWait(fireAnim, fireEvent) +; ;debug.Trace(self + "has finished anim once") + hasPlayedAttackAnimOnce = TRUE + Else + wait(0.5) + endif + finishedPlaying = True + + if (loop == TRUE) ;Reset Limiter +; ;debug.Trace(self + "is looping because loop = " + loop) + resetLimiter() + endif + endWhile + + if isLoaded + isFiring = false + hitBase.goToState("CannotHit") + PlayAnimationAndWait(resetAnim, resetEvent) + goToState("Reset") + endif + ;trace(self + "Reset trap: playanimation(" + resetAnim + ")") + ;trace(self + "Reset trap: waiting for event(" + resetEvent + ")") + + +endFunction +/; + + +Function ResetLimiter() + finishedPlaying = False + ;TrapHitBase hitBase = (self as objectReference) as TrapHitBase + ;hitBase.goToState("CanHit") +EndFunction + +Event onReset() + self.reset() + goToState("Idle") +endEvent + + diff --git a/source/scripts/trapfireplate.psc b/source/scripts/trapfireplate.psc new file mode 100644 index 00000000..c032f81b --- /dev/null +++ b/source/scripts/trapfireplate.psc @@ -0,0 +1,247 @@ +scriptName TrapFirePlate extends TrapTriggerBase +; +; +; +;================================================================ + +int Count ;if Finite = 1, Determines how many times this trigger can be used +int CountUsed ;Used to compare times triggered to max triggers allowed +int Type + +;weapon property pressEffect auto +ammo property pressEffectAmmo auto +hazard property fireHazard auto hidden +objectReference property myHazardRef auto hidden +bool property weaponResolved = false auto hidden +int Property TrapLevel = 1 auto +{Used to determine the difficulty of the trap, currently only tied to damage + 0 = Easy + 1 = Medium (DEFAULT) + 2 = Hard + 3 = VeryHard} + +;event onLoad() + ;objectReference selfRef = self + ;fireHazard = game.getForm(0X0005A1A3) +;endEvent + +State Active + Event onBeginState() + goToState( "DoNothing" ) + if !weaponResolved + ResolveLeveledHazard () + endif + ;pressEffect.fire(selfRef, pressEffectAmmo) + ; EFFECT IS HERE ^^^^^ UNCOMMENT ONCE PROJECTILES OR PARTICLES CAN LEAVE A TRIGGER BOX CORRECTLY + activate(self as objectReference) + ;playAnimationAndWait( "trigger", "reset" ) + TriggerSound.play(self) + playAnimation("Down") + myHazardRef = PlaceAtMe(fireHazard, 1) + if objectsInTrigger == 0 + goToState( "Inactive" ) + playAnimation("Up") + removeMyHazard() + endif + endEvent + + event OnTriggerEnter( objectReference triggerRef ) + if acceptableTrigger(triggerRef) +; ;debug.TRACE(self + " has been entered by " + triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + endif + endEvent + + event OnTrigger( objectReference triggerRef ) + endEvent + + event OnTriggerLeave( objectReference triggerRef ) + ;if acceptableTrigger(triggerRef) +; ;debug.TRACE(self + " has been exited by " + triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + if objectsInTrigger == 0 + goToState ("Inactive") + playAnimation("Up") + removeMyHazard() + endif + ;endif + endEvent +endState + +State DoNothing ;Dummy state, don't do anything if animating + event OnTriggerEnter( objectReference triggerRef ) + if acceptableTrigger(triggerRef) +; ;debug.TRACE(self + " has been entered by " + triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + endif + endEvent + + event OnTrigger( objectReference triggerRef ) + if (triggerRef == game.getPlayer()) && !checkPerks(triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + if objectsInTrigger == 1 + goToState ("Inactive") + playAnimation("Up") + removeMyHazard() + endif + endif + endEvent + + event OnTriggerLeave( objectReference triggerRef ) + ;if acceptableTrigger(triggerRef) +; ;debug.TRACE(self + " has been exited by " + triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + if objectsInTrigger == 0 + goToState ("Inactive") + playAnimation("Up") + removeMyHazard() + endif + ;endif + endEvent +EndState + +;Single point of change for removal of hazard +function removeMyHazard() + objectReference refToRemove = myHazardRef + utility.wait(1.0) + if refToRemove + refToRemove.Disable() + refToRemove.Delete() + endif +endFunction + +auto State Inactive + + event onBeginState() + objectsInTrigger = self.GetTriggerObjectCount() + if (Type == 1 && objectsInTrigger == 0) ;type 1 = hold, so deprecate here if necessary + if (FiniteUse == TRUE && CountUsed < Count);if finite use and count > count used + CountUsed += 1 ;increase count for hold type triggers + endif + + + endif + if objectsInTrigger == 0 + removeMyHazard() + endif + endEvent + + event OnTriggerEnter (objectReference triggerRef) + if acceptableTrigger(triggerRef) +; ;debug.TRACE(self + " has been entered by " + triggerRef) + lastTriggerRef = triggerRef + objectsInTrigger = self.GetTriggerObjectCount() + if (FiniteUse == TRUE && CountUsed < Count) ;if finite use and count > count used + ;TRACE("Finite Use") + if (Type != 1) ;type 1 = hold so only increase on leave + CountUsed += 1 ;increase count used + ;TRACE("Increasing Count on enter") + endif + goToState( "Active" ) + endif + + if (FiniteUse == FALSE) + ;TRACE("Infinite Use") + goToState( "Active" ) + endif + endif + endevent + + event OnTriggerLeave (objectReference triggerRef) + ;if acceptableTrigger(triggerRef) +; ;debug.TRACE(self + " has been exited by " + triggerRef) + lastTriggerRef = triggerRef + objectsInTrigger = self.GetTriggerObjectCount() + if (Type == 1 && objectsInTrigger == 0) ;type 1 = hold, so deprecate here if necessary + if (FiniteUse == TRUE && CountUsed < Count);if finite use and count > count used + CountUsed += 1 ;increase count for hold type triggers + endif + + activate(self as objectReference) + + endif + ;endif + endevent + +endstate + +event onCellAttach() + objectsInTrigger = self.GetTriggerObjectCount() + if !weaponResolved + ResolveLeveledHazard () + endif + if myHazardRef + removeMyHazard() + endif + + if objectsInTrigger == 0 + goToState ("Inactive") + playAnimation("Up") + else + goToState ("Active") + endif +endEvent + +;================================================================ + +int property LvlThreshold1 auto +int property LvlThreshold2 auto +int property LvlThreshold3 auto +int property LvlThreshold4 auto +int property LvlThreshold5 auto +hazard property TrapFirePlateFXHaz01 auto +hazard property TrapFirePlateFXHaz02 auto +hazard property TrapFirePlateFXHaz03 auto +hazard property TrapFirePlateFXHaz04 auto +hazard property TrapFirePlateFXHaz05 auto +hazard property TrapFirePlateFXHaz06 auto + +Function ResolveLeveledHazard () + ;Trace("ResolveLeveledWeapon") + int damageLevel + damageLevel = CalculateEncounterLevel(TrapLevel) + + ; weapon lvlWeaponM = LvlWeaponM1 + ; weapon lvlWeaponL = LvlWeaponL1 + ; weapon lvlWeaponR = LvlWeaponR1 + hazard LvlHazard = TrapFirePlateFXHaz01 + + if (damageLevel > LvlThreshold1 && damageLevel <= LvlThreshold2) + ; lvlWeaponM = LvlWeaponM2 + ; lvlWeaponL = LvlWeaponL2 + ; lvlWeaponR = LvlWeaponR2 + LvlHazard = TrapFirePlateFXHaz02 + ;Trace("damage threshold =") + ;Trace("2") + endif + if (damageLevel > LvlThreshold2 && damageLevel <= LvlThreshold3) + ;lvlWeaponM = LvlWeapon3 + LvlHazard = TrapFirePlateFXHaz03 + ;Trace("damage threshold =") + ;Trace("3") + endif + if (damageLevel > LvlThreshold3 && damageLevel <= LvlThreshold4) + ;lvlWeaponM = LvlWeapon4 + LvlHazard = TrapFirePlateFXHaz04 + ;Trace("damage threshold =") + ;Trace("4") + endif + if (damageLevel > LvlThreshold4 && damageLevel <= LvlThreshold5) + ;lvlWeaponM = LvlWeapon5 + LvlHazard = TrapFirePlateFXHaz05 + ;Trace("damage threshold =") + ;Trace("5") + endif + if (damageLevel > LvlThreshold5) + ;lvlWeaponM = LvlWeapon6 + LvlHazard = TrapFirePlateFXHaz06 + ;Trace("damage threshold =") + ;Trace("6") + endif + + ; ballistaWeaponM = lvlWeaponM + ; ballistaWeaponL = lvlWeaponL + ; ballistaWeaponR = lvlWeaponR + fireHazard = LvlHazard + weaponResolved = True +EndFunction diff --git a/source/scripts/trapgenericeffecthazard.psc b/source/scripts/trapgenericeffecthazard.psc new file mode 100644 index 00000000..9c143744 --- /dev/null +++ b/source/scripts/trapgenericeffecthazard.psc @@ -0,0 +1,207 @@ +scriptName TrapGenericEffectHazard extends TrapBase +;This script is for steam, fire, geysers etc. +; +;================================================================ + +int Count ;if Finite = 1, Determines how many times this trigger can be used +int CountUsed ;Used to compare times triggered to max triggers allowed +int Type + +weapon property pressEffect auto +ammo property pressEffectAmmo auto +hazard property myHazard auto +objectReference myHazardRef +bool property HazardIsPlaced auto hidden +bool property finishedPlaying auto hidden +bool property isFiring auto hidden +bool property isLoaded auto hidden +float property initialDelay = 0.0 auto +float property minimumFiringTime = 3.0 auto +float firingTime + +event onLoad() + objectReference selfRef = self + isLoaded = TRUE + if isFiring == True + fireTrap() + endif +EndEvent + +event onUnload() + isLoaded = FALSE +endEvent + +Function fireTrap() + + ;TRACE("fireTrap called") + isFiring = True + finishedPlaying = False + firingTime = (utility.getCurrentRealTime() + minimumFiringTime) + if WindupSound + WindupSound.play( self as ObjectReference) ;play windup sound + endif + utility.wait( initialDelay ) ;wait for windup + ;TRACE("Initial Delay complete") + trapDisarmed = fireOnlyOnce ;If this can be fired only once then disarm + + if (fireOnlyOnce == True) ;If this can be fired only once then disarm + trapDisarmed = True + endif + + + ;Trap Guts + while(finishedPlaying == False && isLoaded == true) + if (HazardIsPlaced == FALSE) + myHazardRef = PlaceAtMe(myHazard, 1) +; ;debug.Trace(self + "has finished anim once") + HazardIsPlaced = TRUE + Else + utility.wait(0.5) + endif + finishedPlaying = True +; debug.Trace(self + " firingTime == " + firingTime) +; debug.Trace(self + " currentRealTime == " + utility.getCurrentRealTime()) + + if (loop == TRUE || utility.getCurrentRealTime() > firingTime) ;Reset Limiter +; ;debug.Trace(self + "is looping because loop = " + loop) + resetLimiter() + endif + endWhile + + if isLoaded + isFiring = false + myHazardRef.Disable() + myHazardRef.Delete() + goToState("Reset") + endif + + goToState("Reset") + ;TRACE("fireTrap has finished") + +endFunction + +State Reset + Event OnBeginState() + GoToState ( "Idle" ) + endEvent + + Event OnActivate( objectReference activateRef ) + EndEvent +endState + +Function ResetLimiter() + finishedPlaying = False +EndFunction + +;;;;;;;;;;;;;;;;;;;;;;;;; + + +;/ +State Active + Event onBeginState() + goToState( "DoNothing" ) + ;pressEffect.fire(selfRef, pressEffectAmmo) + ; EFFECT IS HERE ^^^^^ UNCOMMENT ONCE PROJECTILES OR PARTICLES CAN LEAVE A TRIGGER BOX CORRECTLY + activate(self as objectReference) + ;playAnimationAndWait( "trigger", "reset" ) + playAnimation("Down") + myHazardRef = PlaceAtMe(myHazard, 1) + if objectsInTrigger == 0 + goToState( "Inactive" ) + playAnimation("Up") + myHazardRef.Disable() + myHazardRef.Delete() + endif + endEvent + + event OnTriggerEnter( objectReference triggerRef ) +; ;debug.TRACE(self + " has been entered by " + triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + endEvent + + event OnTrigger( objectReference triggerRef ) + endEvent + + event OnTriggerLeave( objectReference triggerRef ) +; ;debug.TRACE(self + " has been exited by " + triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + if objectsInTrigger == 0 + goToState ("Inactive") + playAnimation("Up") + myHazardRef.Disable() + myHazardRef.Delete() + endif + endEvent +endState + +State DoNothing ;Dummy state, don't do anything if animating + event OnTriggerEnter( objectReference triggerRef ) +; ;debug.TRACE(self + " has been entered by " + triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + endEvent + + event OnTrigger( objectReference triggerRef ) + endEvent + + event OnTriggerLeave( objectReference triggerRef ) +; ;debug.TRACE(self + " has been exited by " + triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + if objectsInTrigger == 0 + goToState ("Inactive") + playAnimation("Up") + myHazardRef.Disable() + myHazardRef.Delete() + endif + endEvent +EndState + +auto State Inactive + + event onBeginState() + if (Type == 1 && objectsInTrigger == 0) ;type 1 = hold, so deprecate here if necessary + if (FiniteUse == TRUE && CountUsed < Count);if finite use and count > count used + CountUsed += 1 ;increase count for hold type triggers + endif + + activate(self as objectReference) + + endif + endEvent + + event OnTriggerEnter (objectReference triggerRef) +; ;debug.TRACE(self + " has been entered by " + triggerRef) + lastTriggerRef = triggerRef + objectsInTrigger = self.GetTriggerObjectCount() + if (FiniteUse == TRUE && CountUsed < Count) ;if finite use and count > count used + ;TRACE("Finite Use") + if (Type != 1) ;type 1 = hold so only increase on leave + CountUsed += 1 ;increase count used + ;TRACE("Increasing Count on enter") + endif + goToState( "Active" ) + endif + + if (FiniteUse == FALSE) + ;TRACE("Infinite Use") + goToState( "Active" ) + endif + endevent + + event OnTriggerLeave (objectReference triggerRef) +; ;debug.TRACE(self + " has been exited by " + triggerRef) + lastTriggerRef = triggerRef + objectsInTrigger = self.GetTriggerObjectCount() + if (Type == 1 && objectsInTrigger == 0) ;type 1 = hold, so deprecate here if necessary + if (FiniteUse == TRUE && CountUsed < Count);if finite use and count > count used + CountUsed += 1 ;increase count for hold type triggers + endif + + activate(self as objectReference) + + endif + + endevent + +endstate + +/; diff --git a/source/scripts/traphitbase.psc b/source/scripts/traphitbase.psc new file mode 100644 index 00000000..25a75d22 --- /dev/null +++ b/source/scripts/traphitbase.psc @@ -0,0 +1,135 @@ +scriptName TrapHitBase extends objectReference +; +; +; +;========================================= + +import utility + +int property damage auto hidden +int property soundLevel = 10 auto +int property trapPushBack auto +sound property TrapHitSound auto +weapon property hitFX auto +ammo property hitFXAmmo auto +bool property trapCausesStagger = false Auto +{does this trap stagger actors + default = false} +bool property rumble = false Auto +float property rumbleAmount = 0.7 Auto +float property rumbleDuration = 0.5 auto +bool property cameraShake = false Auto +float property cameraShakeAmount = 0.7 auto +float property staggerAmount = 0.0 auto +bool property soundCanPlay = TRUE auto hidden +float property soundDelay = 1.0 auto +bool property throttleSound = TRUE auto +spell property ghostAbility auto +bool property hitOnlyOnce = false auto +{This variable to act as a safety mechanism, +if this is true, after one trap hit this will put itself +into the cannotHit State, Mainly for bearTrap + Default == FALSE} + + +explosion property pushbackExplosion auto +objectReference placedExplosion + +bool property canDisease auto +{this property says whether this can apply diseases on hit + diseaseChance determines the odds if this is true + default = false} + +float property diseaseChance = 2.5 auto +{if canDisease is true, this determines the chance of a disease being applied + default = 2.5%} + +spell property TrapDiseaseAtaxia auto +spell property TrapDiseaseBoneBreakFever auto +spell property TrapDiseaseBrainRot auto +spell property TrapDiseaseRattles auto +spell property TrapDiseaseRockjoint auto +spell property TrapDiseaseWitbane auto + +faction property noHitFaction auto +{This faction will not be affected by hits from this trap} + +;This only processes the hits, another script should tell this one when to be in the CanHit state +state CanHit + Event OnTrapHitStart(ObjectReference akTarget, float afXVel, float afYVel, float afZVel, float afXPos, float afYPos, float afZPos, int aeMaterial, bool abInitialHit, int aeMotionType) +; ;debug.Trace(self + " has hit " + akTarget) + if !(akTarget as actor).hasSpell(ghostAbility) && !(akTarget as actor).IsInFaction(noHitFaction) + if hitOnlyOnce + goToState("CannotHit") + endif + akTarget.ProcessTrapHit(self, damage, trapPushBack, afXVel, afYVel, afZVel, afXPos, afYPos, afZPos, aeMaterial, staggerAmount) + if throttleSound + if soundCanPlay + soundCanPlay = False + if TrapHitSound + TrapHitSound.play( self as ObjectReference) ;play hit sound + endif + registerForSingleUpdate(soundDelay) + endif + Else + TrapHitSound.play( self as ObjectReference) ;play hit sound + endif + + bool isPlayer = false + if akTarget == game.getPlayer() + isPlayer = True + endif + + actor myTarget + myTarget = akTarget as Actor + + if canDisease && isPlayer + if randomFloat(0.0, 100.0) <= diseaseChance + int diseasePick + diseasePick = randomInt(1,6) + if diseasePick == 1 + myTarget.addSpell(TrapDiseaseAtaxia) + elseif diseasePick == 2 + myTarget.addSpell(TrapDiseaseBoneBreakFever) + elseif diseasePick == 3 + myTarget.addSpell(TrapDiseaseBrainRot) + elseif diseasePick == 4 + myTarget.addSpell(TrapDiseaseRattles) + elseif diseasePick == 5 + myTarget.addSpell(TrapDiseaseRockjoint) + elseif diseasePick == 6 + myTarget.addSpell(TrapDiseaseWitbane) + endif + endif + endif + + if hitFX + hitFX.fire(self, hitFxAmmo) + endif + CreateDetectionEvent(myTarget, soundLevel) ; creates a detection event + ;/if trapCausesStagger + placedExplosion = self.placeatme(pushbackExplosion) + placedExplosion.moveto(self, afXoffset = afXpos, afYoffset = afYpos, afZoffset = afZpos) + endif/; + if rumble && isPlayer + game.ShakeController(rumbleAmount, rumbleAmount, rumbleDuration) + EndIf + if cameraShake && isPlayer + game.ShakeCamera(game.getPlayer(),cameraShakeAmount, rumbleDuration) + endif + endif + ;Trace("Damage =") + ;Trace(damage) + + endEvent +endState + +auto state CannotHit + Event OnTrapHit(ObjectReference akTarget, float afXVel, float afYVel, float afZVel, float afXPos, float afYPos, float afZPos, int aeMaterial, bool abInitialHit, int aeMotionType) + endEvent +endState + +event onUpdate() + soundCanPlay = TRUE +EndEvent + \ No newline at end of file diff --git a/source/scripts/traplever.psc b/source/scripts/traplever.psc new file mode 100644 index 00000000..020bbbeb --- /dev/null +++ b/source/scripts/traplever.psc @@ -0,0 +1,10 @@ +scriptName TrapLever extends TrapTriggerBase +; +;This is a stub script to hold parameters that the traps need to see +;================================================ + +auto State Inactive +endState + +State Active +endState diff --git a/source/scripts/trapnorplatform.psc b/source/scripts/trapnorplatform.psc new file mode 100644 index 00000000..445fd98a --- /dev/null +++ b/source/scripts/trapnorplatform.psc @@ -0,0 +1,327 @@ +scriptName TrapNorPlatform extends MovingTrap +; +; +;========================================== + + +;=================================================================== +;;GENERAL PROPERTIES BLOCK +;=================================================================== + +float property FireSpeed = 1.0 Auto +{Time (in seconds) to move from the starting position to the ending position} + +float property ReturnSpeed = 5.0 Auto +{Time (in seconds) to return from the ending position to the starting position} + +float property ReturnDelay = 2.5 Auto +{Time (in seconds) to delay before resetting} + +string midAnim = "Mid" + +string up01Anim = "128Up" +string up02Anim = "256Up" +string up03Anim = "384Up" +string up04Anim = "512Up" +string up05Anim = "640Up" +string up06Anim = "768Up" + +string down01Anim = "128Dn" +string down02Anim = "256Dn" +string down03Anim = "384Dn" +string down04Anim = "512Dn" +string down05Anim = "640Dn" +string down06Anim = "768Dn" + + +;;;;;;;;;;;;;; + +bool restartLooping = false +bool finishedPlaying = false +bool hasPlayedAttackAnimOnce = FALSE +float property initialDelay = 0.25 auto + +string property fireAnim auto hidden +{firing animation, should not need to change} +string property fireSpeedString auto hidden +{firing speed string, name set in script} +string property fireEvent = "Done" auto hidden +{firing animation event, should not need to change} +string property resetAnim auto hidden +{reset animation, should not need to change} +string property resetSpeedString auto hidden +{reset speed string, name set in script} +string property resetEvent = "Done" auto hidden +{reset animation event, should not need to change} +string property startSwungAnim auto hidden +{anim event to start already swung} + +bool property startSwung = false auto +{set to true to start swung} + +hazardBase property myHazardBase auto hidden + +;;;OLD SCRIPT +int property StartingHeight = 0 auto +{The starting height of the platform, -6 to 6 + heights are in increments of 128 + defaults == 0} +;/ {The starting height of the platform, -6 to 6, defaults to 0} + int Function Get() + return StartingHeight + endFunction + + Function Set (int value) + if (value >= 6 && value <= 6) + StartingHeight = Value + else + StartingHeight = 0 + endif + endFunction +endProperty/; + +int property EndingHeight = 3 auto + {The ending height of the platform, -6 to 6 + heights are in increments of 128 + defaults == 3} +;/ int Function Get() + return EndingHeight + endFunction + + Function Set (int value) + if (value >= 6 && value <= 6) + EndingHeight = Value + else + EndingHeight = 3 + endif + endFunction +endProperty/; + +;=================================================================== +;;EVENT BLOCK +;=================================================================== + + +EVENT OnLoad() + ;/if (startSwung == true ) + ;trace(self + "OnLoad: playanimation(" + startSwungAnim + ")") + playAnimation(startSwungAnim) ;activator starts opened + endif/; + +; debug.Trace(self + " has called onLoad") + SetResetAnim() + SetFireAnim() + myHazardBase = (self as objectReference) as hazardBase + isLoaded = TRUE + if isFiring == True || startSwung == True + startSwung = False + if startSwung + loop == True + endif + fireTrap() + endif +endEVENT + + +;=================================================================== +;;FIRE TRAP BLOCK +;=================================================================== + +Function fireTrap() + + ;Basic wind up and fire once checking +; debug.TRACE(self + " has called fireTrap") +; debug.TRACE(self + ": lastActivateRef = " + lastActivateRef) + isFiring = True + myHazardBase.goToState("CanHit") + WindupSound.play( self as ObjectReference) ;play windup sound + ResolveLeveledDamage() + SetResetAnim() + SetFireAnim() + utility.wait( initialDelay ) ;wait for windup + hasPlayedAttackAnimOnce = FALSE + ;TRACE("Initial Delay complete") + + if (fireOnlyOnce == True) ;If this can be fired only once then disarm + trapDisarmed = True + endif + + ;TRACE("Looping =") + ;TRACE(Loop) + + ;Trap Guts + while(finishedPlaying == False && isLoaded == true) + ;trace(self + "Firing trap: playanimation(" + fireAnim + ")") + ;trace(self + "Firing trap: waiting for event(" + fireEvent + ")") + if (hasPlayedAttackAnimOnce == FALSE) + fireSpeedString = FireAnim + fireSpeedString + "s" + SetAnimationVariableFloat(fireSpeedString, FireSpeed) + PlayAnimationAndWait(fireAnim, fireEvent) +; ;debug.Trace(self + "has finished anim once") + hasPlayedAttackAnimOnce = TRUE + + Else + utility.wait(0.5) + endif + finishedPlaying = True + + if (loop == TRUE) ;Reset Limiter +; ;debug.Trace(self + "is looping because loop = " + loop) + resetLimiter() + endif + endWhile + myHazardBase.goToState("CannotHit") + resetSpeedString = resetAnim + resetSpeedString + "s" + SetAnimationVariableFloat(resetSpeedString, ReturnSpeed) + utility.wait(ReturnDelay) + + if isLoaded + isFiring = false + PlayAnimationAndWait(resetAnim, resetEvent) + goToState("Reset") + endif + ;trace(self + "Reset trap: playanimation(" + resetAnim + ")") + ;trace(self + "Reset trap: waiting for event(" + resetEvent + ")") + + +endFunction + +State Reset + + Event OnBeginState() + GoToState ( "Idle" ) + myHazardBase = (self as objectReference) as hazardBase + if myHazardBase + myHazardBase.goToState("CannotHit") + endif + endEvent + + Event OnActivate( objectReference activateRef ) + lastActivateRef = activateRef + EndEvent + +endState + +;=================================================================== +;;FUNCTION BLOCK +;=================================================================== + +Function ResetLimiter() + finishedPlaying = False + ;hazardBase myHazardBase = (self as objectReference) as hazardBase + ;myHazardBase.goToState("CanHit") +EndFunction + + +Function SetResetAnim() + if startingHeight == -6 + ResetAnim = down06Anim + ElseIf startingHeight == -5 + ResetAnim = down05Anim + ElseIf startingHeight == -4 + ResetAnim = down04Anim + ElseIf startingHeight == -3 + ResetAnim = down03Anim + ElseIf startingHeight == -2 + ResetAnim = down02Anim + ElseIf startingHeight == -1 + ResetAnim = down01Anim + ElseIf startingHeight == 0 + ResetAnim = midAnim + ElseIf startingHeight == 1 + ResetAnim = up01Anim + ElseIf startingHeight == 2 + ResetAnim = up02Anim + ElseIf startingHeight == 3 + ResetAnim = up03Anim + ElseIf startingHeight == 4 + ResetAnim = up04Anim + ElseIf startingHeight == 5 + ResetAnim = up05Anim + ElseIf startingHeight == 6 + ResetAnim = up06Anim + Endif +EndFunction + +Function SetFireAnim() + if EndingHeight == -6 + FireAnim = down06Anim + ElseIf EndingHeight == -5 + FireAnim = down05Anim + ElseIf EndingHeight == -4 + FireAnim = down04Anim + ElseIf EndingHeight == -3 + FireAnim = down03Anim + ElseIf EndingHeight == -2 + FireAnim = down02Anim + ElseIf EndingHeight == -1 + FireAnim = down01Anim + ElseIf EndingHeight == 0 + FireAnim = midAnim + ElseIf EndingHeight == 1 + FireAnim = up01Anim + ElseIf EndingHeight == 2 + FireAnim = up02Anim + ElseIf EndingHeight == 3 + FireAnim = up03Anim + ElseIf EndingHeight == 4 + FireAnim = up04Anim + ElseIf EndingHeight == 5 + FireAnim = up05Anim + ElseIf EndingHeight == 6 + FireAnim = up06Anim + Endif + + startSwungAnim = FireAnim +EndFunction + + +Function ResolveLeveledDamage() + int damageLevel + int damage + damageLevel = CalculateEncounterLevel(TrapLevel) + + damage = LvlDamage1 + + if (damageLevel > LvlThreshold1 && damageLevel <= LvlThreshold2) + damage = LvlDamage2 + ;Trace("damage threshold =") + ;Trace("2") + endif + if (damageLevel > LvlThreshold2 && damageLevel <= LvlThreshold3) + damage = LvlDamage3 + ;Trace("damage threshold =") + ;Trace("3") + endif + if (damageLevel > LvlThreshold3 && damageLevel <= LvlThreshold4) + damage = LvlDamage4 + ;Trace("damage threshold =") + ;Trace("4") + endif + if (damageLevel > LvlThreshold4 && damageLevel <= LvlThreshold5) + damage = LvlDamage5 + ;Trace("damage threshold =") + ;Trace("5") + endif + if (damageLevel > LvlThreshold5) + damage = LvlDamage6 + ;Trace("damage threshold =") + ;Trace("6") + endif + + ;Trace("damage =") + ;Trace(damage) + + ;return damage + myHazardBase = (self as objectReference) as hazardBase + if myHazardBase + myHazardBase.damage = damage + endif +EndFunction + + + + + diff --git a/source/scripts/trapoilpool.psc b/source/scripts/trapoilpool.psc new file mode 100644 index 00000000..8324f18b --- /dev/null +++ b/source/scripts/trapoilpool.psc @@ -0,0 +1,184 @@ +scriptName TrapOilPool extends TrapExplosiveGas +; +; +;============================================== + +; form fireHazard +;objectReference myHazardRef + +float property burnDuration = 30.0 auto +{duration that the pool burns for} +string oilAnim = "stopeffect" +string oilDisappearEvent ="end" +objectReference myLinkedRef +bool lightIsOn = False +bool property lightStaysOn = False auto +{if set to 'TRUE' the enabled linked ref will not get disabled when the oil pool is destroyed} +;used to track if we have turned on our linkedRef light yet + +bool property deleteSelfAfterIgnition = True auto +{whether or not the oil pool is used up after burning + default == true} + +;bool hazardAssigned = False +explosion property OilExplosion auto ;hidden +bool property weaponResolved = false auto hidden +int Property TrapLevel = 1 auto +{Used to determine the difficulty of the trap, currently only tied to damage + 0 = Easy + 1 = Medium (DEFAULT) + 2 = Hard + 3 = VeryHard} + +; event onLoad() + ; fireHazard = game.getForm(0X0005A1A3) + ; hazardAssigned = True +; endEvent + +;/ +event onCellAttach() + if !weaponResolved + ResolveLeveledExplosion() + endif +endEvent +/; + +Function gasExplode(objectReference causeActor) + ;if (causeActor as actor) + self.setActorCause(causeActor as actor) + ;endif + goToState("DoNothing") + ;if hazardAssigned == False + ; AssignHazard() + ;endif + ;myHazardRef = PlaceAtMe(fireHazard, 1) + (self as objectReference).damageObject(5.0) + myLinkedRef = getLinkedRef() + if myLinkedRef && !lightIsOn + lightIsOn = True + myLinkedRef.enable() + endif + + + +endFunction + +state doNothing + + event onHit(objectReference akAggressor, form akWeapon, projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + endEvent + + event OnMagicEffectApply(ObjectReference akCaster, MagicEffect akEffect) + endEvent + + event onTriggerEnter(objectReference triggerRef) + endEvent + +endState + +; function AssignHazard() + ; fireHazard = game.getForm(0X0005A1A3) + ; hazardAssigned = True +; endFunction + +event OnDestructionStageChanged(int aiOldStage, int aiCurrentStage) + myLinkedRef = getLinkedRef() + ;if !weaponResolved + ; ResolveLeveledExplosion() + ;endif + + if aiCurrentStage == 2 + placeAtMe(OilExplosion) + endif + if aiCurrentStage < 3 && !lightIsOn && myLinkedRef + lightIsOn = True + myLinkedRef.enable() + endif +; debug.Trace(self + " has received destruction event #" + aiCurrentStage) + if aiCurrentStage == 3 + if deleteSelfAfterIgnition + playanimationandwait(oilAnim, oilDisappearEvent) + endif + + if !lightStaysOn && myLinkedRef + myLinkedRef.disable() + endif + + if deleteSelfAfterIgnition + self.Disable() + else + self.reset() + self.clearDestruction() + goToState("Waiting") + endif + endif +endEvent + +;/ + +;================================================================ + +int property LvlThreshold1 auto +int property LvlThreshold2 auto +int property LvlThreshold3 auto +int property LvlThreshold4 auto +int property LvlThreshold5 auto +Explosion property TrapOilExplosion01 auto +Explosion property TrapOilExplosion02 auto +Explosion property TrapOilExplosion03 auto +Explosion property TrapOilExplosion04 auto +Explosion property TrapOilExplosion05 auto +Explosion property TrapOilExplosion06 auto + +Function ResolveLeveledExplosion () + ;Trace("ResolveLeveledWeapon") + int damageLevel + damageLevel = CalculateEncounterLevel(TrapLevel) + + ; weapon lvlWeaponM = LvlWeaponM1 + ; weapon lvlWeaponL = LvlWeaponL1 + ; weapon lvlWeaponR = LvlWeaponR1 + explosion LvlExplosion = TrapOilExplosion01 + + if (damageLevel > LvlThreshold1 && damageLevel <= LvlThreshold2) + ; lvlWeaponM = LvlWeaponM2 + ; lvlWeaponL = LvlWeaponL2 + ; lvlWeaponR = LvlWeaponR2 + LvlExplosion = TrapOilExplosion02 + ;Trace("damage threshold =") + ;Trace("2") + endif + if (damageLevel > LvlThreshold2 && damageLevel <= LvlThreshold3) + ;lvlWeaponM = LvlWeapon3 + LvlExplosion = TrapOilExplosion03 + ;Trace("damage threshold =") + ;Trace("3") + endif + if (damageLevel > LvlThreshold3 && damageLevel <= LvlThreshold4) + ;lvlWeaponM = LvlWeapon4 + LvlExplosion = TrapOilExplosion04 + ;Trace("damage threshold =") + ;Trace("4") + endif + if (damageLevel > LvlThreshold4 && damageLevel <= LvlThreshold5) + ;lvlWeaponM = LvlWeapon5 + LvlExplosion = TrapOilExplosion05 + ;Trace("damage threshold =") + ;Trace("5") + endif + if (damageLevel > LvlThreshold5) + ;lvlWeaponM = LvlWeapon6 + LvlExplosion = TrapOilExplosion06 + ;Trace("damage threshold =") + ;Trace("6") + endif + + ; ballistaWeaponM = lvlWeaponM + ; ballistaWeaponL = lvlWeaponL + ; ballistaWeaponR = lvlWeaponR + OilExplosion = LvlExplosion + weaponResolved = True +EndFunction + + +/; diff --git a/source/scripts/trappoisongas.psc b/source/scripts/trappoisongas.psc new file mode 100644 index 00000000..d59dee95 --- /dev/null +++ b/source/scripts/trappoisongas.psc @@ -0,0 +1,393 @@ +scriptName TrapPoisonGas extends objectReference +; +; +;=================================================================== +;;Properties from MQShoutTrigger +;=================================================================== + +Spell property voicelv01 auto ; level 1 shout +Spell property voicelv02 auto ; and 2 +Spell property voicelv03 auto ; and 3, the most powerful + +float property timeToClear auto hidden ; this variable is set according to what power of shout hit the fog + +float property ClearTimeWeak = 5.0 auto +{tweak setting for how long fog stays cleared by weakest shout + default = 5.0} + +float property ClearTimeMed = 10.0 auto +{tweak setting for how long fog stays cleared by medium shout + default = 10.0} + +float property ClearTimeStrong = 15.0 auto +{tweak setting for how long fog stays cleared by strongest shout + default = 15.0} + +bool property allowEnableFlag = true auto +{when true, trigger will enable after clear time is up + when false, trigger will stay disabled} + +; return value for IsFogOn function +; hidden property for use in child scripts +bool property bIsFogOn = false auto hidden + +explosion property PoisonGasExplosion auto hidden +bool property weaponResolved = false auto hidden +int Property TrapLevel = 1 auto +{Used to determine the difficulty of the trap, currently only tied to damage + 0 = Easy + 1 = Medium (DEFAULT) + 2 = Hard + 3 = VeryHard} + +;=================================================================== +;;Gas Properties +;=================================================================== + +keyword property gasKeyword auto +magicEffect property gasMagicEffect01 Auto +float property fDuration = 15.0 auto +bool property isInitiallyActive = True auto +{Set whether the poison gas is initially active + default == TRUE} + +bool property init = FALSE auto hidden +bool property TemporarilyCleared auto hidden +bool property loop = False auto hidden + +;=================================================================== +;;EVENT BLOCK +;=================================================================== + +event onCellLoad() + if !init && isInitiallyActive + goToState("On") ;onAnim + bIsFogOn = true + loop = true + init = TRUE + else + init = TRUE + endif + + if !weaponResolved + ResolveLeveledExplosion () + endif +endEvent + +;=================================================================== +;;STATE BLOCK +;=================================================================== + +;/ +STATE WaitingForTrigger + event onBeginState() + if !weaponResolved + ResolveLeveledExplosion () + endif + endEvent + + event onTrigger(objectReference triggerRef) +; Debug.Trace("Triggered: " + triggerRef + " " + !(triggerRef as actor).HasMagicEffectWithKeyword(gasKeyword)) + if triggerRef as actor + if !(triggerRef as actor).HasMagicEffectWithKeyword(gasKeyword) +; debug.Trace(self + " has applied gas to " + triggerRef) + ;(triggerRef as actor).addSpell(gasSpell01) + triggerRef.placeAtMe(PoisonGasExplosion) + endif + endif + endEvent + + ; event OnTriggerEnter (objectReference TriggerRef) + ; resolveTriggerLogic(triggerRef) + ; endEvent + + Event OnHit(ObjectReference Aggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + if Aggressor == Game.GetPlayer() + resolveTriggerLogic(None, (akSource as spell)) + endif + endEvent + + event onActivate(objectReference activateRef) + ResolveGasActivation(activateRef) + endEvent +endState + + +STATE HasBeenTriggered + ; Nothing happens - this is a holding state + EVENT OnHit(ObjectReference akAggressor, Form akWeapon, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) +; debug.Trace("Hit but inactive: "+self) + endEVENT +endSTATE + +STATE Inactive + event onActivate(objectReference activateRef) + ResolveGasActivation(activateRef) + endEvent +endSTATE +/; + +;;;;;;;;;;;;;;;;;;;;New stuff;;;;;;;;;;;;;;;;;;;;;;;;; + +State On + event onBeginState() + bIsFogOn = True + playAnimation("playAnim02") ;onAnim + endEvent + + ;Currently has an actor inside + event onTrigger(objectReference triggerRef) + if triggerRef as actor && !(triggerRef as actor).isDead() + + ;If the actor does not already have a poison effect on them + if !(triggerRef as actor).HasMagicEffectWithKeyword(gasKeyword) +; debug.Trace(self + " has applied gas to " + triggerRef) + ;(triggerRef as actor).addSpell(gasSpell01) + triggerRef.placeAtMe(PoisonGasExplosion) + endif + endif + endEvent + + ;Activated by a trap trigger object + event onActivate(objectReference activateRef) + ResolveGasActivation(activateRef) + endEvent + + ;This occurs when hit by a shout + Event OnHit(ObjectReference Aggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + if Aggressor == Game.GetPlayer() && (akSource as spell) + resolveShoutLogic(akSource as spell) + endif + endEvent +endState + +auto State Off + event onBeginState() + bIsFogOn = False + playAnimation("playAnim01") ;offAnim + endEvent + + event onActivate(objectReference activateRef) + ResolveGasActivation(activateRef) + endEvent +endState + +State TempCleared + event onBeginState() + bIsFogOn = False + playAnimation("playAnim01") ;offAnim + utility.wait(timeToClear) + if TemporarilyCleared + TemporarilyCleared = False + goToState("On") + else + goToState("Off") + endif + + endEvent + + event onActivate(objectReference activateRef) + ResolveGasActivation(activateRef) + endEvent +endState +;=================================================================== +;;FUNCTION BLOCK +;=================================================================== + +Function ResolveShoutLogic(Spell akSpell) +; debug.Trace(self + "MQShoutTrigger: fireTriggerEvent from " + akSpell) + TemporarilyCleared = True + ; set the time that this fog portion will stay cleared based on strength of the shout + if akSpell == voicelv01 + timeToClear = clearTimeWeak + elseif akSpell == voicelv02 + timeToClear = clearTimeMed + elseif akSpell == voicelv03 + timeToClear = clearTimeStrong + endif + goToState("TempCleared") + ;setFogState(false) +; ;debug.Trace(self + "Waiting " + timeToClear) + ;utility.wait(timeToClear) + ; if allowEnableFlag + ;self.enable() + ; setFogState(true) + ; endif + ; goToState("WaitingForTrigger") +endFunction + +; Function resolveTriggerLogic(ObjectReference TriggerRef = None, Spell SpellRef = None) + + ;respond if struck by one of the shout projectiles +; ; debug.Trace( self + "MQShoutTrigger: resolveTriggerLogic ObjectRef=" + TriggerRef + ", SpellRef=" + spellRef) + + ; if spellRef;&& (spellRef == voicelv01 || spellRef == voicelv02 || spellRef == voicelv03) + ; goToState("HasBeenTriggered") + ; fireTriggerEvent(spellRef) + ; endif + +; endFunction + +;Handle turning on or off +function ResolveGasActivation(objectReference activateRef) + TrapTriggerBase TriggerRef ;TriggerRef will always be a TrapTriggerBase + TriggerRef = activateRef as TrapTriggerBase ;Set TriggerRef to our activateRef + + if TriggerRef + if TriggerRef.TriggerType == 0 ;single + loop = False + if bIsFogOn + ;do nothing + + Else + ;turn on + unregisterForUpdate() + registerForSingleUpdate(fDuration) + goToState("On") ;onAnim + endif + elseif TriggerRef.TriggerType == 1 ;hold + + if loop + loop = False + else + loop = True + endif + + if bIsFogOn + ;turn off + if TemporarilyCleared + TemporarilyCleared = False + else + goToState("Off") ;offAnim + endif + Else + ;turn on + goToState("On") ;onAnim + endif + elseif TriggerRef.TriggerType == 2 ;toggle + if bIsFogOn + loop = False + ;turn off + if TemporarilyCleared + TemporarilyCleared = False + else + goToState("Off") ;offAnim + endif + Else + loop = True + ;turn on + goToState("On") ;onAnim + endif + elseif TriggerRef.TriggerType == 3 ;turn on + loop = True + if bIsFogOn + ;do nothing + else + ;turn on + goToState("On") ;onAnim + endif + elseif TriggerRef.TriggerType == 4 ;turn off + loop = False + if bIsFogOn + ;turn off + if TemporarilyCleared + TemporarilyCleared = False + else + goToState("Off") ;offAnim + endif + Else + ;do nothing + endif + endif + Else + + endif +endFunction + +event onUpdate() + unregisterForUpdate() + if getState() == "On" + if !loop + goToState("Off") + endif + elseif getState() == "TempCleared" + TemporarilyCleared = False + else + endif +endEvent +; Function setFogState(bool bTurnOnFog) + ; bIsFogOn = bTurnOnFog + ; if bTurnOnFog +; ; debug.Trace("Re-fogging: "+self) + ; self.enable() + ; else +; ; debug.Trace("unfogging: "+self) + ; self.disable() + ; endif +; endFunction + +;================================================================ + +int property LvlThreshold1 auto +int property LvlThreshold2 auto +int property LvlThreshold3 auto +int property LvlThreshold4 auto +int property LvlThreshold5 auto +Explosion property TrapPoisonGasExplosion01 auto +Explosion property TrapPoisonGasExplosion02 auto +Explosion property TrapPoisonGasExplosion03 auto +Explosion property TrapPoisonGasExplosion04 auto +Explosion property TrapPoisonGasExplosion05 auto +Explosion property TrapPoisonGasExplosion06 auto + +Function ResolveLeveledExplosion () + ;Trace("ResolveLeveledWeapon") + int damageLevel + damageLevel = CalculateEncounterLevel(TrapLevel) + + ; weapon lvlWeaponM = LvlWeaponM1 + ; weapon lvlWeaponL = LvlWeaponL1 + ; weapon lvlWeaponR = LvlWeaponR1 + explosion LvlExplosion = TrapPoisonGasExplosion01 + + if (damageLevel > LvlThreshold1 && damageLevel <= LvlThreshold2) + ; lvlWeaponM = LvlWeaponM2 + ; lvlWeaponL = LvlWeaponL2 + ; lvlWeaponR = LvlWeaponR2 + LvlExplosion = TrapPoisonGasExplosion02 + ;Trace("damage threshold =") + ;Trace("2") + endif + if (damageLevel > LvlThreshold2 && damageLevel <= LvlThreshold3) + ;lvlWeaponM = LvlWeapon3 + LvlExplosion = TrapPoisonGasExplosion03 + ;Trace("damage threshold =") + ;Trace("3") + endif + if (damageLevel > LvlThreshold3 && damageLevel <= LvlThreshold4) + ;lvlWeaponM = LvlWeapon4 + LvlExplosion = TrapPoisonGasExplosion04 + ;Trace("damage threshold =") + ;Trace("4") + endif + if (damageLevel > LvlThreshold4 && damageLevel <= LvlThreshold5) + ;lvlWeaponM = LvlWeapon5 + LvlExplosion = TrapPoisonGasExplosion05 + ;Trace("damage threshold =") + ;Trace("5") + endif + if (damageLevel > LvlThreshold5) + ;lvlWeaponM = LvlWeapon6 + LvlExplosion = TrapPoisonGasExplosion06 + ;Trace("damage threshold =") + ;Trace("6") + endif + + ; ballistaWeaponM = lvlWeaponM + ; ballistaWeaponL = lvlWeaponL + ; ballistaWeaponR = lvlWeaponR + PoisonGasExplosion = LvlExplosion + weaponResolved = True +EndFunction + + \ No newline at end of file diff --git a/source/scripts/trappoisongascough.psc b/source/scripts/trappoisongascough.psc new file mode 100644 index 00000000..916c73fe --- /dev/null +++ b/source/scripts/trappoisongascough.psc @@ -0,0 +1,69 @@ +scriptName TrapPoisonGasCough extends ActiveMagicEffect +{used to make the player cough when they are poisoned +by gas and to throw detection events} +;=========================================================== +float property fCoughTime = 5.0 auto +float property fCoughRand = 2.0 auto + +float property afSmallMotorStrength = 0.2 auto +float property afBigMotorStrength = 0.2 auto +float property afDuration = 1.0 auto + +actor myActor +sound property tempSound Auto +{temp sound till we can have the player "say" a line} +bool stateActive = false +float coughTime +topic property DialogueGenericPoisonCoughBranchTopic auto +bool myActorIsPlayer = false + +auto State Waiting + Event OnEffectStart(Actor akTarget, Actor akCaster) + myActor = akTarget + goToState("active") + endEvent + +endState + +state active + event onBeginState() + stateActive = TRUE + if myActor == game.getPlayer() + myActorIsPlayer = True + endif + CoughLoop() + endEvent + + event OnEffectFinish(Actor akTarget, Actor akCaster) + stateActive = FALSE + goToState("Waiting") + endEvent +endState + +function coughLoop() + while stateActive + utility.wait(randTimerFloat()) + DoCough() + endWhile +endFunction + +function DoCough() + ;game.getPlayer().say(cough) + ;tempSound.play(myActor) + myActor.say(DialogueGenericPoisonCoughBranchTopic) + if myActorIsPlayer + myActor.createDetectionEvent(myActor, 30) + game.ShakeController(afSmallMotorStrength, afBigMotorStrength, afDuration) + endif +endFunction + +float function randTimerFloat() + float fReturn = fCoughTime + utility.RandomFloat((0-fCoughRand), fCoughRand) + return fReturn +endFunction + +Event OnEffectStart(Actor akTarget, Actor akCaster) +endEvent + +event OnEffectFinish(Actor akTarget, Actor akCaster) +endEvent diff --git a/source/scripts/trapriggedrockfall.psc b/source/scripts/trapriggedrockfall.psc new file mode 100644 index 00000000..597d5b72 --- /dev/null +++ b/source/scripts/trapriggedrockfall.psc @@ -0,0 +1,19 @@ +scriptName TrapRiggedRockfall Extends TrapBase +; +; +;============================================= + + +auto State Idle + + event onActivate (objectReference activateRef) + goToState("DoNothing") +; ;debug.TRACE("Idle trigger") + lastActivateRef = activateRef + playAnimation("break") + ;activate rocks if necessary + endEvent +endState + +state DoNothing +endState diff --git a/source/scripts/traprockfalleffects.psc b/source/scripts/traprockfalleffects.psc new file mode 100644 index 00000000..0eadcc22 --- /dev/null +++ b/source/scripts/traprockfalleffects.psc @@ -0,0 +1,57 @@ +scriptName trapRockfallEffects extends objectReference +; +; +;==================================== + +bool property doOnce = true auto +{if true do this only once + default == true} + +bool property placeAll = true auto +{default == true + if true place all things that have been set + if false place the first thing that we find set} + +explosion property placedExplosion auto +objectReference property placedObjectRef auto +sound property rockfallSound Auto +objectReference objSelf +float ControllerShakeL = 0.5 +float ControllerShakeR = 0.5 +float ControllerShakeDuration = 1.5 +bool property cannedHallwayDust = false auto +{used for precanned dust in hallways} +string anim01 = "playAnim01" +string animEndEvent = "endAnim" + +auto state waiting + + event onActivate(objectReference triggerRef) + goToState("DoNothing") + objSelf = self as objectReference + rockfallSound.play(objSelf) + game.ShakeCamera(afStrength = 1.0) + game.ShakeController(ControllerShakeL, ControllerShakeR, ControllerShakeDuration) + if cannedHallwayDust + playAnimationAndWait(anim01, animEndEvent) + Else + placeAllThings() + endif + endEvent + +endState + +state DoNothing + event onActivate(objectReference triggerRef) + endEvent +endState + +function placeAllThings() + if placedExplosion + self.placeAtMe(placedExplosion) + endif + + if placedObjectRef + self.placeAtMe(placedExplosion) + endif +endFunction diff --git a/source/scripts/trapsoulgemcontroller.psc b/source/scripts/trapsoulgemcontroller.psc new file mode 100644 index 00000000..1806c24c --- /dev/null +++ b/source/scripts/trapsoulgemcontroller.psc @@ -0,0 +1,131 @@ +scriptName trapSoulGemController extends objectReference +; +; +;======================================================= + +objectReference property objSelf auto hidden +objectReference property myMagicTrap auto hidden +float idleRotateSpeed = 1.0 + + +;/ +event onAttachedToCell() +; ;debug.Trace(self + " is firing onCellLoad, activation should be blocked") + objSelf = self as objectReference + self.blockActivation() +endEvent +/; + + +auto state waiting + event onBeginState() + EndEvent + + event onHit(objectReference akAggressor, form akWeapon, projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + endEvent + + event onMagicEffectApply(ObjectReference akCaster, MagicEffect akEffect) + EndEvent + + event onGrab() + endEvent +endState + + +state inMagicTrap + event onBeginState() + (self as objectReference).SetMotionType(4) +; ;debug.Trace(self + " has begun inMagicTrap") + ;self.TranslateTo(self.getpositionx(), self.getpositiony(), self.getpositionz(), self.getAngleX(), self.getAngleY() + 180, self.getAngleZ(), idleRotateSpeed) + endEvent + + event onHit(objectReference akAggressor, form akWeapon, projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + + ;self.stopTranslation() + (self as objectReference).SetMotionType(1) +; ;debug.Trace(self + " has been hit") + goToState("disarmed") + endEvent + + event onMagicEffectApply(ObjectReference akCaster, MagicEffect akEffect) + ;self.stopTranslation() + (self as objectReference).SetMotionType(1) +; ;debug.Trace(akCaster + " has cast " + akEffect + " on " + self) + goToState("disarmed") + endEvent + + event onGrab() + ;self.stopTranslation() + (self as objectReference).SetMotionType(1) +; ;debug.Trace(self + " has been grabbed") + goToState("disarmed") + endEvent + +endstate + +state disarmed + event onBeginState() + magicTrap myTrap + myTrap = (getLinkedRef() as magicTrap) + myTrap.clearMySoulgem() + endEvent +endState + + +event OnActivate(objectReference akActivator) +; ;debug.Trace(self + " has recieved onActivate from " + akActivator) +; ;debug.Trace(self + " is checking if:" + akActivator + " == " + game.getPlayer()) + if akActivator == game.getPlayer() + goToState("disarmed") + self.disable() + ;self.delete() + objSelf = self as objectReference + if objSelf + (game.getPlayer() as actor).addItem(objSelf.getBaseObject(), 1, false) + else +; ;debug.Trace(self + ": objSelf was not set!") + endif + else +; ;debug.Trace(akActivator + " != " + game.getPlayer()) + endif +endEvent + +event onCellAttach() +; Debug.Trace(self + ": onCellAttach called") + objSelf = self as objectReference + self.blockActivation() + + objSelf = self as objectReference + objectReference gemSelf = objSelf + + magicTrap myTrap + myTrap = (getLinkedRef() as magicTrap) + + + if self.isEnabled() +; Debug.Trace(self + ": is enabled") + if myTrap ;&& !myTrap.gemTested + myTrap.CellAttachSetUp(gemSelf) + ;elseif myTrap && myTrap.gemTested +; ; debug.Trace(self + ": myTrap has already resolved the gem") + else +; debug.Trace(self + ": has no linked ref. This is bad.") + endif + else +; Debug.Trace(self + ": is not enabled") + endif +endEvent + +event onReset() +; debug.Trace(self + ": is running onReset") +; debug.Trace(self + ": onResetCalled") + self.enable(AbFadein = false) + self.reset() + objSelf = self as objectReference + objectReference gemSelf = objSelf + goToState("waiting") + +endEvent + + + diff --git a/source/scripts/traptriggerbase.psc b/source/scripts/traptriggerbase.psc new file mode 100644 index 00000000..a62e23a6 --- /dev/null +++ b/source/scripts/traptriggerbase.psc @@ -0,0 +1,390 @@ +scriptName TrapTriggerBASE extends objectReference hidden +; +; +;This is the base trap trigger script and handles what the trigger tells the trap +;Any trigger should be useable with any trap +;Activation params are on the trigger, toggle, number of times it can be triggered, etc. +;Trap params are on the trap (damage, timing, etc) +;Some triggers will be extended from this base to handle animation, etc. +;================================================================ + +import debug + + +int Count ;if Finite = 1, Determines how many times this trigger can be used +int property CountUsed auto hidden ;Used to compare times triggered to max triggers allowed +int property Type auto hidden ;This is to determine trigger to send to the trap + ;The trap will handle its behavior based on this signal + ;0 = Single - fire the trap once do one time + ;1 = Hold - on entry turn on, on exit turn off + ;2 = Toggle - on entry or use toggle trap state + ;3 = Turn On - on entry or use turn on trap + ;4 = Turn Off - on entry or use turn off trap +sound property TriggerSound auto +objectReference property lastTriggerRef auto hidden +int property soundLevel = 10 auto + +int objInTriggerVar +int property objectsInTrigger hidden + function set(int value) + objInTriggerVar = value + ;TraceStack("Setting objectsInTrigger to " + value) + endFunction + int function get() + return objInTriggerVar + endFunction +endProperty + +faction property owningFaction Auto +actorBase property owningActorBase Auto +bool property doOnceBase = False auto hidden +bool property playerOnlyTrigger = false auto +bool property checkForLightFootPerk = false Auto +{Setting this will give a chance that the trap trigger will not Fire + this does not work on triggers with the HOLD trigger type + Set on by default on all pressure plates + you should only mess with this locally for triggerboxes} +bool property checkForLightHandsPerk = false Auto +{Setting this will give a chance that the trap trigger will not Fire when lockpicked + this is used specifically for hinge triggers or other things like that + set to on by default on the hinge trigger} +perk property lightFootPerk Auto +globalVariable property LightFootGlobalVar auto +perk property lightHandsPerk Auto +globalVariable property LightHandsGlobalVar auto + +bool property blockActivate = false Auto +{block activation of this by the player, only used for trapLinker + default = False} + +bool property FiniteUse auto + {If true this has a finite number of uses as defined by the TriggerCount, and then will not fire} + +bool property isTriggerVolume = False auto +{This property is used to tell the trap trigger if it is a trigger volume + if true, on cell attach it will try to check if there are object in the trigger and go to state inactive if not + This should be turned to TRUE for pressure plates & triggerboxes + default = false} + +int property TriggerCount + {the number of times this Trigger can fire, only used if FiniteUse is True} + int Function Get() + return Count + endFunction + + Function Set (int value) + if (value >= 1 && value <= 100) + Count = Value + else + Count = 1 + endif + endFunction +endProperty + +int property TriggerType + {This property determines how the trigger will tell the trap to fire + 0 = Single Fire + 1 = Hold + 2 = Toggle + 3 = Turn On + 4 = Turn Off} + int Function Get() + return Type + endFunction + + Function Set (int value) + if (value >= 0 && value <= 4) + Type = value + StoredTriggerType = Value + else + Type = 0 + StoredTriggerType = 0 + endif + endFunction +endProperty + +int property StoredTriggerType auto Hidden +{this stores what the triggerType was set to on the Ref + used for trapLinker in case of activation by non trapTriggerBase ref} + +event onCellAttach() + if self.GetFactionOwner() + owningFaction = self.GetFactionOwner() + ElseIf self.GetActorOwner() + owningActorBase = (self.GetActorOwner() as actorBase) + endif + + if blockActivate + self.blockActivation(true) + endif + + ;/ + if !doOnceBase + StoredTriggerType = TriggerType + doOnceBase = True + endif + /; +endEvent + +Event onCellLoad() + objectsInTrigger = self.GetTriggerObjectCount() + if isTriggerVolume && objectsInTrigger == 0 + goToState ("Inactive") + endif +endEvent + +;THIS SECTION IS USED FOR TRAP LINKERS +event onActivate(objectReference akActivator) +; debug.Trace(self + " has been activated by + " + akActivator) +; debug.Trace(self + ": Type = " + Type + ", StoredTriggerType = " + StoredTriggerType) + if blockActivate && akActivator != (self as objectReference) + if (akActivator as trapTriggerBase) +; debug.Trace(akActivator + " was able to be cast as trapTriggerBase") +; debug.Trace(self + " triggerType was " + triggerType) + TriggerType = (akActivator as trapTriggerBase).TriggerType +; debug.Trace(self + " triggerType is now " + triggerType) + + + else +; debug.Trace(akActivator + " was NOT able to be cast as trapTriggerBase") + triggerType = StoredTriggerType + endif + + if blockActivate + self.blockActivation(false) + utility.wait(0.0) + localActivateFunction() + self.Activate(self) + self.blockActivation(true) + endif + + endif +endEvent + +;================================================================ + +auto State Inactive + + event onBeginState() +; debug.Trace(self + ": is calling onBeginState Inactive") +; debug.Trace(self + ": StoredTriggerType = " + StoredTriggerType + ", objectsInTrigger = " + objectsInTrigger) + if (StoredTriggerType == 1 && objectsInTrigger == 0) ;type 1 = hold, so deprecate here if necessary + if (FiniteUse == TRUE && CountUsed < Count);if finite use and count > count used + CountUsed += 1 ;increase count for hold type triggers + endif + Type = 4 + utility.wait(0.1) + activate(self as objectReference) + utility.wait(0.1) + ;Type = 1 + else +; debug.Trace(self + "StoredTriggerType = " + StoredTriggerType + ", ObjectsInTrigger = " + objectsInTrigger) + endif + endEvent + + event OnTriggerEnter (objectReference triggerRef) + if acceptableTrigger(triggerRef) +; debug.Trace(self + " has been entered by " + triggerRef) + lastTriggerRef = triggerRef + objectsInTrigger = self.GetTriggerObjectCount() + if (FiniteUse == TRUE && CountUsed < Count) ;if finite use and count > count used + ;TRACE("Finite Use") + if (Type != 1) ;type 1 = hold so only increase on leave + CountUsed += 1 ;increase count used + ;TRACE("Increasing Count on enter") + endif + goToState( "Active" ) + endif + + if (FiniteUse == FALSE) + ;TRACE("Infinite Use") + goToState( "Active" ) + endif + endif + endevent + + event OnTriggerLeave (objectReference triggerRef) + if acceptableTrigger(triggerRef) +; debug.Trace(self + " has been exited by " + triggerRef) + lastTriggerRef = triggerRef + objectsInTrigger = self.GetTriggerObjectCount() +; debug.Trace(self + ": StoredTriggerType = " + StoredTriggerType + ", objectsInTrigger = " + objectsInTrigger) + if (StoredTriggerType == 1 && objectsInTrigger == 0) ;type 1 = hold, so deprecate here if necessary + if (FiniteUse == TRUE && CountUsed < Count);if finite use and count > count used + CountUsed += 1 ;increase count for hold type triggers + endif + Type = 4 + utility.wait(0.1) + activate(self as objectReference) + utility.wait(0.1) + ;Type = 1 + endif + endif + endevent + +endstate + + +State Active + Event onBeginState() +; debug.Trace(self + ": is calling onBeginState Active") +; debug.Trace(self + ": StoredTriggerType = " + StoredTriggerType + ", objectsInTrigger = " + objectsInTrigger) + if (StoredTriggerType == 1) + Type = 3 + utility.wait(0.1) + activate(self as objectReference) + utility.wait(0.1) + ;Type = 1 + else + activate(self as objectReference) + endif + + if objectsInTrigger == 0 + goToState( "Inactive" ) + endif + endEvent + + event OnTriggerEnter( objectReference triggerRef ) + if acceptableTrigger(triggerRef) +; debug.Trace(self + " has been entered by " + triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + endif + endEvent + + event OnTriggerLeave( objectReference triggerRef ) + if acceptableTrigger(triggerRef) +; debug.Trace(self + " has been exited by " + triggerRef) + objectsInTrigger = self.GetTriggerObjectCount() + if objectsInTrigger == 0 + goToState ("Inactive") + endif + endif + endEvent + + event OnMagicEffectApply(objectReference akCaster, MagicEffect akEffect) + Trace("MagicEffectHit") + activate(self as objectReference) + goToState( "Inactive" ) + endEvent +endState + +;The following function is used to filter for acceptable objects to trigger this +;if it is player only, then ONLY the player will trigger it and nothing else, including projectiles +;if there is an owning faction and it is not player only then everything BUT actors + ;that are part of that owning faction will trigger it +bool function acceptableTrigger(objectReference triggerRef) + +; debug.Trace(self + " is checking if " + triggerRef + " is an acceptable trigger") + if playerOnlyTrigger + if triggerRef == game.getPlayer() +; debug.Trace(self + " has found that " + triggerRef + " is an acceptable trigger") + if checkPerks(triggerRef) + Return True + Else + Return False + endif + Else +; debug.Trace(self + " has found that " + triggerRef + " is not an acceptable trigger") + return False + endif + Else + if !(triggerRef as actor) ;if this is not a player only trigger and this is not an actor + return True + elseif owningFaction + if (triggerRef as actor).IsInFaction(owningFaction) +; debug.Trace(self + " has found that " + triggerRef + " is not an acceptable trigger") + return False + else +; debug.Trace(self + " has found that " + triggerRef + " is an acceptable trigger") + if checkPerks(triggerRef) + Return True + Else + Return False + endif + endif + else + if owningActorBase + if (triggerRef as actor).getActorBase() == owningActorBase +; debug.Trace(self + " has found that " + triggerRef + " is not an acceptable trigger") + return False + Else +; debug.Trace(self + " has found that " + triggerRef + " is an acceptable trigger") + if checkPerks(triggerRef) + Return True + Else + Return False + endif + endif + else +; debug.Trace(self + " has found that " + triggerRef + " is an acceptable trigger") + if checkPerks(triggerRef) + Return True + Else + Return False + endif + endif + endif + endif +endFunction + +Bool function checkPerks(objectReference triggerRef) + if checkForLightFootPerk +; debug.Trace(self + " is checking if " + triggerRef + " has LightFoot Perk") + if (triggerRef as actor).hasPerk(lightFootPerk) +; debug.Trace(self + " has found that " + triggerRef + " has LightFoot Perk") + if utility.randomFloat(0.0,100.00) <= LightFootGlobalVar.getValue() +; debug.Trace(self + " is returning false due to failed lightfoot roll") + return False + else +; debug.Trace(self + " is returning true due to successful lightfoot roll") + return True + endif + Else +; debug.Trace(self + " has found that " + triggerRef + " doesn't have the LightFoot Perk") + Return True + EndIf + elseif checkForLightHandsPerk +; debug.Trace(self + " is checking if " + triggerRef + " has LightHands Perk") + if (triggerRef as actor).hasPerk(lightHandsPerk) +; debug.Trace(self + " has found that " + triggerRef + " has LightFoot Perk") + if utility.randomFloat(0.0,100.00) <= LightHandsGlobalVar.getValue() +; debug.Trace(self + " is returning false due to failed lightHands roll") + return False + else +; debug.Trace(self + " is returning true due to successful lightHands roll") + return True + endif + Else +; debug.Trace(self + " has found that " + triggerRef + " doesn't have the LightFoot Perk") + Return True + EndIf + Else +; debug.Trace(self + " has found that " + triggerRef + " doesn't have applicable perks") + return True + EndIf +endFunction + +function localActivateFunction() ;placeholder function for anything that may need to be on the child activate event +endFunction + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/scripts/traptriggerhinge.psc b/source/scripts/traptriggerhinge.psc new file mode 100644 index 00000000..23ee264a --- /dev/null +++ b/source/scripts/traptriggerhinge.psc @@ -0,0 +1,102 @@ +scriptName TrapTriggerHinge extends TrapTriggerBase +; +; +; +;================================================================ + + +int popmessage +bool triggeredOnce = False +objectReference objectSelf +objectReference trapLinkedRef +keyword property TrapKeyword auto +message property LockpickMessage auto +sound property disarmSound auto + +event onCellLoad() + objectSelf = self as ObjectReference + trapLinkedRef = getLinkedRef(TrapKeyword) as objectReference + if trapLinkedRef as trapTriggerBase + (trapLinkedRef as trapTriggerBase).triggerType = triggertype + endif +endEvent + +auto State Active + ;Over ride trapTriggerBase events + event onBeginState() + endevent + + event onTriggerEnter(objectReference triggerRef) + endevent + + event onTriggerLeave(objectReference triggerRef) + endevent + + event OnMagicEffectApply(objectReference akCaster, MagicEffect akEffect) + endevent + + ;Activation + event onActivate(objectReference triggerRef) + if triggerRef as actor == game.getPlayer() + if !isLocked() + goToState("Disarmed") + endif + else +; ;;Debug.Trace(self + " has been activated by " + triggerRef) + goToState("Triggered") + EndIf + EndEvent + + event onLockStateChanged() + if !isLocked() + goToState("Disarmed") + elseif isLockBroken() + goToState("Triggered") + else + ;goToState("Active") + endif + endEvent + + event onHit(ObjectReference akAggressor, Form akWeapon, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + if TriggeredOnce == False +; ;Debug.Trace(self + " has been hit by " + akAggressor) + goToState("Triggered") + EndIf + EndEvent +EndState + + + +state Disarmed + event onBeginState() + if disarmSound + disarmSound.play(self) + endif + playanimation("Disarm01") + setDestroyed(true) + EndEvent +EndState + +state Triggered + event onBeginState() + (trapLinkedRef).activate(objectSelf) + setDestroyed(true) + playAnimation("Trigger01") + EndEvent +endState + +event onTriggerEnter(objectReference triggerRef) +endEvent + +event onTriggerLeave(objectReference triggerRef) +endEvent + +state Inactive +endState + +event onReset() + self.Reset() + self.clearDestruction() + self.setDestroyed(False) + goToState("Active") +endEvent diff --git a/source/scripts/traptriggertimeinterval.psc b/source/scripts/traptriggertimeinterval.psc new file mode 100644 index 00000000..6df4d030 --- /dev/null +++ b/source/scripts/traptriggertimeinterval.psc @@ -0,0 +1,56 @@ +scriptName TrapTriggerTimeInterval extends TrapTriggerBase +; +; +;======================================================== + +float property initialDelay = 0.1 Auto +float property initialDelayRange = 0.1 auto + +float property triggerInterval = 15.0 auto +{how often to trigger the trap, EG: every 15.0 seconds + default = 15.0} +float property triggerIntervalRange = 3.0 auto +{random amount of time to increase/decrease the triggerInterval + default = 3.0} +;NOTE: make sure that triggerInterval cannot be 0 or less. + +float lowerTriggerIntervalRange +bool property isLoaded = false auto hidden +Cell property myParentCell auto hidden + +auto state TimedFireState + + event onCellAttach() +; debug.Trace(self + ": should be loaded") + isLoaded = true + lowerTriggerIntervalRange = (0.0 - triggerIntervalRange) + myParentCell = self.getParentCell() + registerForSingleUpdate(math.abs(initialDelay + utility.RandomFloat(0.0, InitialDelayRange))) + endEvent + + event onCellDetach() +; debug.Trace(self + ": should be unloaded") + isLoaded = false + endEvent + + + event onUpdate() +; debug.Trace(self + ": has ran an update at timestamp: " + utility.getCurrentRealTime()) + if myParentCell.isAttached() + utility.wait(0.0) + self.activate(self) +; debug.Trace(self + ": has found that 3d is loaded") + registerForSingleUpdate(triggerInterval + utility.RandomFloat(lowerTriggerIntervalRange, triggerIntervalRange)) + else +; debug.Trace(self + ": has found that 3d is NOT loaded") + isLoaded = false + endif + endEvent +endState + + +event onCellAttach() +endEvent + +event onCellDetach() +endEvent diff --git a/source/scripts/tripwire.psc b/source/scripts/tripwire.psc new file mode 100644 index 00000000..03178d51 --- /dev/null +++ b/source/scripts/tripwire.psc @@ -0,0 +1,81 @@ +scriptName Tripwire extends TrapTriggerBase +; +; +; +;================================================================ +; event onActivate(objectReference akActivator) + ; if (akActivator as actor) && akActivator != (self as objectReference) + ; goToState("Active") + ; endif +; endEvent + + +State Active + Event OnBeginState() + SetMotionType(1) + TriggerSound.play( self as ObjectReference) ;play trigger sound + self.blockActivation(false) + activate(self as objectReference) + self.blockActivation(true) + PlayAnimation("Trigger") + goToState("DoNothing") + ;applyHavokImpulse 15 0 0 -1 ;push down at a force of 15 to break the havok constraint. + + endEvent + + event onActivate(objectReference akActivator) + endEvent + + event OnTriggerEnter( objectReference triggerRef ) + endEvent + + event OnTriggerLeave( objectReference triggerRef ) + endEvent + + Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) + endEvent +endState + +State DoNothing ;Dummy state, don't do anything if animating + event onBeginState() + setDestroyed(true) + endEvent + + event OnTriggerEnter( objectReference triggerRef ) + endEvent + + event OnTriggerLeave( objectReference triggerRef ) + endEvent + + event onCellAttach() + endEvent +EndState + +Event OnCellAttach() + SetMotionType(4) +EndEvent + +;/ +Event OnCellDetach() + SetMotionType(1) +EndEvent +/; + +function localActivateFunction() + goToState("Active") +endFunction + +Event onReset() + self.reset() + SetMotionType(4) + self.clearDestruction() + self.setDestroyed(False) + goToState("Inactive") + CountUsed = 0 +endEvent + +Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) +; ;debug.Trace(self + ": was hit by " + akAggressor + " with " + akSource + " or " + akProjectile) + goToState("Active") +endEvent + diff --git a/source/scripts/voiceiceformscript.psc b/source/scripts/voiceiceformscript.psc new file mode 100644 index 00000000..3e59e2dc --- /dev/null +++ b/source/scripts/voiceiceformscript.psc @@ -0,0 +1,11 @@ +Scriptname VoiceIceFormScript extends ActiveMagicEffect + +Event OnEffectStart (Actor akTarget, Actor akCaster) + akTarget.ModActorValue("MagicResist", 99) + akTarget.ModActorValue("DamageResist", 500) +EndEvent + +Event OnEffectFinish (Actor akTarget, Actor akCaster) + akTarget.ModActorValue("MagicResist", -99) + akTarget.ModActorValue("DamageResist", -500) +EndEvent \ No newline at end of file diff --git a/source/scripts/voiceobjectscript.psc b/source/scripts/voiceobjectscript.psc new file mode 100644 index 00000000..35a5936c --- /dev/null +++ b/source/scripts/voiceobjectscript.psc @@ -0,0 +1,18 @@ +Scriptname VoiceObjectScript extends ObjectReference + +Topic Property SaidTopic Auto + +Actor Property Speaker Auto + +Event OnLoad() + Say(SaidTopic, Speaker, false) + RegisterForSingleUpdate(5.0) +EndEvent + +Event OnUpdate() + Disable() + Delete() +endEvent + +Event OnUnload() +EndEvent \ No newline at end of file diff --git a/source/scripts/voicepusheffectscript.psc b/source/scripts/voicepusheffectscript.psc new file mode 100644 index 00000000..ce5003a5 --- /dev/null +++ b/source/scripts/voicepusheffectscript.psc @@ -0,0 +1,7 @@ +Scriptname VoicePushEffectScript extends ActiveMagicEffect + +Event OnEffectStart(actor Target, actor Caster) + Caster.PushActorAway(Target, PushForce) +EndEvent + +int Property PushForce Auto diff --git a/source/scripts/weaponracktriggerscript.psc b/source/scripts/weaponracktriggerscript.psc new file mode 100644 index 00000000..456e2a30 --- /dev/null +++ b/source/scripts/weaponracktriggerscript.psc @@ -0,0 +1,102 @@ +Scriptname WeaponRackTriggerSCRIPT extends ObjectReference Hidden + +import game +import debug +import utility + +Keyword Property WRackActivator Auto + +;The activator we must disable if there is already something in this trigger +ObjectReference Property ActivatorRef Auto Hidden + +;Reference that is currently in the trigger +ObjectReference Property RefCurrentlyInTrig Auto Hidden + +;1 = if something is in this trigger, 0 = empty +Bool Property HasBeenTriggered Auto Hidden + +Int Property numInTrig Auto Hidden + +Bool Property AlreadyInit Auto Hidden + +Bool Property IgnoreArmor = FALSE Auto + + +EVENT OnReset() + AlreadyInit = FALSE + ;Trace("DARYL - " + self + " running OnReset() and AlreadyInit = " + AlreadyInit) +endEVENT + +EVENT OnLoad() + ;Trace("DARYL - " + self + " running OnLoad() and AlreadyInit = " + AlreadyInit) + if (AlreadyInit == FALSE) && (self.IsEnabled()) + ActivatorRef = GetLinkedRef(WRackActivator) + if (ActivatorRef) + ActivatorRef.Enable() + endif + ActivatorRef = NONE + AlreadyInit = TRUE + ;Trace("DARYL - " + self + " The Activator Ref is " + ActivatorRef) + else + ;Do nothing + endif + ;Trace("DARYL - " + self + " finishing OnLoad() and AlreadyInit = " + AlreadyInit) +endEVENT + +;EVENT OnCellLoad() +; ;Trace("DARYL - " + self + " running OnCellLoad() and AlreadyInit = " + AlreadyInit) +; if (AlreadyInit == FALSE) && (self.IsEnabled()) +; ActivatorRef = GetLinkedRef(WRackActivator) +; AlreadyInit = TRUE +; ;Trace("DARYL - " + self + " The Activator Ref is " + ActivatorRef) +; else +; ;Do nothing +; endif +; ;Trace("DARYL - " + self + " finishing OnCellLoad() and AlreadyInit = " + AlreadyInit) +;endEVENT + + +auto STATE WaitingForReference + EVENT onTriggerEnter(objectReference triggerRef) + ;Trace("DARYL - " + self + " Just OnTriggerEntered by " + triggerref) + + if (IgnoreArmor == TRUE) && (triggerRef.GetBaseObject() as Armor) + ;Trace("DARYL - " + self + " I'm ignoring armor, and this is armor, so I'm doing nothing.") + ;Do Nothing + else + ;Trace("DARYL - " + self + " I'm updating as normal") + ;numInTrig = (numInTrig + 1) + HasBeenTriggered = TRUE + ActivatorRef = GetLinkedRef(WRackActivator) + if ActivatorRef + ActivatorRef.Disable() + endif + ActivatorRef = NONE + endif + + + endEVENT + EVENT OnTriggerLeave(objectReference triggerRef) + ;Trace("DARYL - " + self + " A References has EXITED, refs in this trigger now = " + numInTrig) + + if (IgnoreArmor == TRUE) && (triggerRef.GetBaseObject() as Armor) + ;Trace("DARYL - " + self + " I'm ignoring armor, and this is armor, so I'm doing nothing.") + ;Do Nothing + else + ;Trace("DARYL - " + self + " I'm updating as normal") + ;numInTrig = (numInTrig - 1) + endif + + if (GetTriggerObjectCount() == 0) + ActivatorRef = GetLinkedRef(WRackActivator) + + HasBeenTriggered = FALSE + ActivatorRef.Enable() + + ActivatorRef = NONE + + endif + endEVENT +endSTATE + + diff --git a/source/scripts/webdestructiblescript.psc b/source/scripts/webdestructiblescript.psc new file mode 100644 index 00000000..5c3bb484 --- /dev/null +++ b/source/scripts/webdestructiblescript.psc @@ -0,0 +1,74 @@ +Scriptname WebDestructibleSCRIPT extends ObjectReference + +import debug +import utility + +Quest property myQuest auto +{the quest to manipulate when web is destroyed} + +Int property myQuestStageOnFirstStage auto +{if needed, the stage to set when web hits first stage of destruction} + +Int property myQuestStageOnDestroyed auto +{if needed, the stage to set when web is destroyed} + +ObjectReference property webActor auto +{the actor stuck in the web} + +ObjectReference property webTrigger auto +{the trigger calling random animations on actor in web and web itself} + +Scene property myScene01 auto +{if needed, the scene to start when web hits its first stage} + +Scene property myScene02 auto +{if needed, the scene to start when web is destroyed} + + + +Event OnDestructionStageChanged(int aiOldStage, int aiCurrentStage) + + if(aiCurrentStage == 1) + if(myQuest) + myQuest.setStage(myQuestStageOnFirstStage) + ;if there is a scene to start, then start the scene + endif + + if(myScene01) + myScene01.start() + endif + endif + + if(aiCurrentStage == 2) + ;web is destroyed + + ;if there's a trigger controlling the random web animations, then need to set its stopCondition + if(webTrigger) + SpiderWebAnimationsSCRIPT myWebTrigger = webTrigger as SpiderWebAnimationsSCRIPT + myWebTrigger.stopCondition = true + myWebTrigger.gotoState("done") + endif + + ;if there's an actor in the web, set his variable and get him out + if(webActor) + Actor myActor = webActor as Actor + myActor.setav("Variable03", 5) + myActor.evaluatePackage() + endif + + ;if there is a quest to manipulate, then set the stage + if(myQuest) + myQuest.setStage(myQuestStageOnDestroyed) + endif + + ;if there is a scene to start, then start the scene + if(myScene02) + if(!myScene01.isPlaying()) + myScene02.start() + endif + endif + + ;animate the web + playAnimation("Exit") + endif +endEvent diff --git a/source/scripts/werewolfchangeeffectscript.psc b/source/scripts/werewolfchangeeffectscript.psc new file mode 100644 index 00000000..feac8cfc --- /dev/null +++ b/source/scripts/werewolfchangeeffectscript.psc @@ -0,0 +1,41 @@ +Scriptname WerewolfChangeEffectScript extends ActiveMagicEffect +{Scripted effect for the werewolf change} + + + +;======================================================================================; +; PROPERTIES / +;=============/ + +Quest Property PlayerWerewolfQuest auto +Quest Property C00 auto + +Spell Property VFXSpell auto + + +;======================================================================================; +; EVENTS / +;=============/ + +Event OnEffectStart(Actor Target, Actor Caster) +; Debug.Trace("WEREWOLF: Casting transformation spell on " + Target) + + ; set up tracking + if (Target == Game.GetPlayer()) +; Debug.Trace("WEREWOLF: Target is player.") + ; if this is the first time, don't actually do anything (transform handled in rampage script) + if ( (C00 as CompanionsHousekeepingScript).PlayerIsWerewolfVirgin ) +; Debug.Trace("WEREWOLF: Player's first time; bailing out.") + (C00 as CompanionsHousekeepingScript).PlayerIsWerewolfVirgin = false + Game.SetBeastForm(False) + return + endif + +; Debug.Trace("WEREWOLF: Starting player tracking.") + + PlayerWerewolfQuest.Start() + endif + + VFXSpell.Cast(Target) +EndEvent + diff --git a/source/scripts/werewolftransformvisual.psc b/source/scripts/werewolftransformvisual.psc new file mode 100644 index 00000000..48f31fd2 --- /dev/null +++ b/source/scripts/werewolftransformvisual.psc @@ -0,0 +1,65 @@ +Scriptname WerewolfTransformVisual extends ActiveMagicEffect + +Armor Property WolfSkinFXArmor auto +Race Property WerewolfRace auto + +VisualEffect property FeedBloodVFX auto +Idle Property IdleWerewolfTransformation auto +Sound Property NPCWerewolfTransformation auto +Sound Property NPCWerewolfTransformationB2D auto +Sound Property NPCWerewolfTransformationB3D auto + +Quest Property PlayerWerewolfQuest auto + +Event OnEffectStart(Actor Target, Actor Caster) +; Debug.Trace("WEREWOLF: Starting change anim...") + + if (Target.GetActorBase().GetRace() != WerewolfRace) + ; Add the tranformation wolf skin Armor effect + Target.equipitem(WolfSkinFXArmor,False,True) + + RegisterForAnimationEvent(Target, "SetRace") + Target.PlayIdle(IdleWerewolfTransformation) + Utility.Wait(10) + TransformIfNecessary(Target) + endif +EndEvent + +Event OnAnimationEvent(ObjectReference akSource, string asEventName) +; Debug.Trace("WEREWOLF: Getting anim event -- " + akSource + " " + asEventName) + if (asEventName == "SetRace") + TransformIfNecessary(akSource as Actor) + endif +EndEvent + +Function TransformIfNecessary(Actor Target) + if (Target == None) +; Debug.Trace("WEREWOLF: Trying to transform something that's not an actor; bailing out.", 2) + return + endif + + UnRegisterForAnimationEvent(Target, "SetRace") + + Race currRace = Target.GetRace() + if (currRace != WerewolfRace) +; Debug.Trace("WEREWOLF: VISUAL: Setting race " + WerewolfRace + " on " + Target) + if (Target != Game.GetPlayer()) +; Debug.Trace("WEREWOLF: VISUAL: Target is not player, doing the transition here.") + Target.SetRace(WerewolfRace) ;TEEN WOLF + + ; Remove the transformation effect armor if he/she has it on. + if (Target.GetItemCount(WolfSkinFXArmor) > 0) + (Target.Removeitem(WolfSkinFXArmor, 1, True, none)) + endif + else + CompanionsHousekeepingScript chs = (PlayerWerewolfQuest as PlayerWerewolfChangeScript).CompanionsTrackingQuest as CompanionsHousekeepingScript + if (chs.PlayerOriginalRace == None) + chs.PlayerOriginalRace = currRace + endif + PlayerWerewolfQuest.SetStage(1) + endif + + endif +EndFunction + + diff --git a/source/scripts/wifunctionsscript.psc b/source/scripts/wifunctionsscript.psc new file mode 100644 index 00000000..1128c582 --- /dev/null +++ b/source/scripts/wifunctionsscript.psc @@ -0,0 +1,496 @@ +Scriptname WIFunctionsScript extends Quest Conditional +{A place to hold functions that more than one world interaction quest might need that require properties I don't want to have to set up more than once.} + +;HOW TO USE THIS: Make this Quest a property cast as this quest, in the calling quest, and then you can access it's functions using the properties set up on WI quest. + +MiscObject Property Gold001 Auto + +;These are factions used by the function to make people mourn Kill event victims +faction property pWIMournAuntFaction auto +faction property pWIMournBoyfriendFaction auto +faction property pWIMournBrotherFaction auto +faction property pWIMournCousinFemaleFaction auto +faction property pWIMournCousinMaleFaction auto +faction property pWIMournDaughterFaction auto +faction property pWIMournFatherFaction auto +faction property pWIMournFriendFemaleFaction auto +faction property pWIMournFriendMaleFaction auto +faction property pWIMournGirlfriendFaction auto +faction property pWIMournHusbandFaction auto +faction property pWIMournKinsmanFaction auto +faction property pWIMournKinswomanFaction auto +faction property pWIMournMotherFaction auto +faction property pWIMournNephewFaction auto +faction property pWIMournNieceFaction auto +faction property pWIMournSisterFaction auto +faction property pWIMournSonFaction auto +faction property pWIMournUncleFaction auto +faction property pWIMournWifeFaction auto + +Faction Property WIAssaultedFaction Auto + +faction Property WIPlayerEnemyFaction Auto + +;used for WIDragonKill scene when the player absorbs power - see MQKillDragonScript +Faction Property WIDragonKilledAbsorbedFaction Auto +GlobalVariable Property WINextDragon Auto +GlobalVariable Property WIWaitDragon Auto + +;Note: this is a subset of all the AssociationTypes because this script only cares about these types. +associationType property pAuntUncle auto +associationType property pCourting auto +associationType property pCousins auto +associationType property pParentChild auto +associationType property pSiblings auto +associationType property pSpouse auto + + + +;WIDeadBodyCleanUpScript properties: +GlobalVariable Property GameDaysPassed Auto +faction property WINoBodyCleanupFaction auto +ObjectReference Property WIDeadBodyCleanupCellMarker Auto + +;Keywords +Keyword Property WIGamesTagStart Auto +Keyword Property WIDragonKilledStart Auto + +Keyword Property WIComplexInteractionToggle Auto ;used to control complex interactions, keyword data >= 0 complex interactions like dragon attacks are allowed, < 0 means not allowed to occur at this Location +Keyword Property WIDragonsToggle Auto + +Keyword Property WIDragonAttacked Auto ;used by the DragonActorScript to set keyword data on locations that have been attacked so people can respond to that fact + +Keyword Property WIRentRoomWalkToStart Auto + +;Locations + +Location Property SolitudeLocation Auto +Location Property MarkarthLocation Auto +Location Property WhiterunLocation Auto +Location Property WindhelmLocation Auto +Location Property RiftenLocation Auto + +Location Property BattleBornFarmLocation Auto +Location Property ChillfurrowFarmLocation Auto +Location Property LeftHandMineLocation Auto +Location Property MerryfairFarmLocation Auto +Location Property SalviusFarmLocation Auto +Location Property SnowShodFarmLocation Auto +Location Property PelagiaFarmLocation Auto + + + + +;Quests +Quest property WIGamesTag auto +Quest property MQ305 auto + + +Event OnInit() + +; debug.trace(self + " OnInit() turning off dragon WI events in cities and settlements near them") + + DisallowDragons(SolitudeLocation) + DisallowDragons(MarkarthLocation) + DisallowDragons(WhiterunLocation) + DisallowDragons(WindhelmLocation) + DisallowDragons(RiftenLocation) + + DisallowDragons(BattleBornFarmLocation) + DisallowDragons(ChillfurrowFarmLocation) + DisallowDragons(LeftHandMineLocation) + DisallowDragons(MerryfairFarmLocation) + DisallowDragons(SalviusFarmLocation) + DisallowDragons(SnowShodFarmLocation) + DisallowDragons(PelagiaFarmLocation) + + +EndEvent + + + +function RemoveMournerActorFromFactions(Actor Mourner) + + Mourner.RemoveFromFaction(pWIMournAuntFaction) + Mourner.RemoveFromFaction(pWIMournBoyfriendFaction) + Mourner.RemoveFromFaction(pWIMournBrotherFaction) + Mourner.RemoveFromFaction(pWIMournCousinFemaleFaction) + Mourner.RemoveFromFaction(pWIMournCousinMaleFaction) + Mourner.RemoveFromFaction(pWIMournDaughterFaction) + Mourner.RemoveFromFaction(pWIMournFatherFaction) + Mourner.RemoveFromFaction(pWIMournFriendFemaleFaction) + Mourner.RemoveFromFaction(pWIMournFriendMaleFaction) + Mourner.RemoveFromFaction(pWIMournGirlfriendFaction) + Mourner.RemoveFromFaction(pWIMournHusbandFaction) + Mourner.RemoveFromFaction(pWIMournKinsmanFaction) + Mourner.RemoveFromFaction(pWIMournKinswomanFaction) + Mourner.RemoveFromFaction(pWIMournMotherFaction) + Mourner.RemoveFromFaction(pWIMournNephewFaction) + Mourner.RemoveFromFaction(pWIMournNieceFaction) + Mourner.RemoveFromFaction(pWIMournSisterFaction) + Mourner.RemoveFromFaction(pWIMournSonFaction) + Mourner.RemoveFromFaction(pWIMournUncleFaction) + Mourner.RemoveFromFaction(pWIMournWifeFaction) +endFunction + +function PutMournerAliasInFaction(ReferenceAlias VictimAlias, ReferenceAlias MournerAlias) +{Calls PutMournerActorInFaction passing VictimAlias and MournerAlias as actors. Based on the relationship of the Victim to Mourner, mourer is placed in a faction to get related dialogue.} + + if MournerAlias.GetReference() == None + ;bail out earlu + return + EndIf + + actor VictimActor = VictimAlias.GetReference() as Actor + actor MournerActor = MournerAlias.GetReference() as Actor + + if VictimActor && MournerActor ;double check the cast before passing in as actor + PutMournerActorInFaction(VictimActor, MournerActor) + else +; debug.trace("WIFunctionsScript: PutMournerAliasInFaction expected ReferenceAliases that could be cast as actors, got some other kind of ReferenceAlias. Victim: " + VictimAlias.GetReference() +", Mourner: " + MournerAlias.GetReference() + ".") + endif + +endFunction + +function PutMournerActorInFaction(Actor Victim, Actor Mourner) +{Based on the relationship of the Victim to Mourner, mourer is placed in a faction to get related dialogue.} + string relation = GetRelationshipString(Victim, Mourner) + + if relation == "aunt" + Mourner.AddToFaction(pWIMournAuntFaction) + elseif relation == "boyfriend" + Mourner.AddToFaction(pWIMournBoyfriendFaction) + elseif relation == "brother" + Mourner.AddToFaction(pWIMournBrotherFaction) + elseif relation == "cousin female" + Mourner.AddToFaction(pWIMournCousinFemaleFaction) + elseif relation == "cousin male" + Mourner.AddToFaction(pWIMournCousinMaleFaction) + elseif relation == "daughter" + Mourner.AddToFaction(pWIMournDaughterFaction) + elseif relation == "father" + Mourner.AddToFaction(pWIMournFatherFaction) + elseif relation == "friend female" + Mourner.AddToFaction(pWIMournFriendFemaleFaction) + elseif relation == "friend male" + Mourner.AddToFaction(pWIMournFriendMaleFaction) + elseif relation == "girlfriend" + Mourner.AddToFaction(pWIMournGirlfriendFaction) + elseif relation == "husband" + Mourner.AddToFaction(pWIMournHusbandFaction) + elseif relation == "kinsman" + Mourner.AddToFaction(pWIMournKinsmanFaction) + elseif relation == "kinswoman" + Mourner.AddToFaction(pWIMournKinswomanFaction) + elseif relation == "mother" + Mourner.AddToFaction(pWIMournMotherFaction) + elseif relation == "nephew" + Mourner.AddToFaction(pWIMournNephewFaction) + elseif relation == "niece" + Mourner.AddToFaction(pWIMournNieceFaction) + elseif relation == "sister" + Mourner.AddToFaction(pWIMournSisterFaction) + elseif relation == "son" + Mourner.AddToFaction(pWIMournSonFaction) + elseif relation == "uncle" + Mourner.AddToFaction(pWIMournUncleFaction) + elseif relation == "wife" + Mourner.AddToFaction(pWIMournWifeFaction) + else +; debug.trace("WIFunctionsScript PutMournerInFaction() returned unexpected relation variable: " + relation + " when Actor1 is " + Victim + " and Actor2 is " + Mourner + ".") + + endif + +endFunction + +string function GetRelationshipString(Actor Actor1, Actor Actor2) +{Returns a string based on Actor1's relationship to Actor2 (ie if Actor1 is in Sibling relationship and a male, returns "brother") Note: Not all relationship types are supported by this function. See function comments for details.} + string sex ;"male" | "female" - CASE SENSITIVE description of Actor1 + string position ;"parent" | "child" - CASE SENSITIVE description of Actor1 (ie if Actor1 is niece, then = "child", if Actor1 is aunt then = "parent") + string relation ;"kinsman", "father", "sister", "friend male", "boyfriend", etc. - CASE SENSTIVE description of Actor1 + ;Supported replationships: + ;Friend: + ; "friend male", "friend female" + ;Family: + ; "kinsman", "kinswoman" + ; "husband", "wife" + ; "father", "mother" + ; "son", "daughter" + ; "brother", "sister" + ; "uncle", "aunt" + ; "nephew", "niece" + ; "cousin male", "cousin female" + ;Boyfriend/Girlfriend: + ; "boyfriend", "girlfriend" + + ;sex + if Actor1.getActorBase().getSex() == 0 ;male + sex = "male" + else ;female + sex = "female" + endif + + ;parent/child + if Actor1.hasParentRelationship(Actor2) ;We have set up data, so someone is never both a parent and a child in different relationshps to the same person + position = "parent" + else ;child + position = "child" + endif + + ;friend male/friend female + ;we set the relation to be friend if there's any family relation at all. This will get "overwritten" if we discover a more specific relationship + if Actor1.GetRelationshipRank(Actor2) >= 1 + if sex == "male" + relation = "friend male" + else ;female + relation = "friend female" + endif + endif + + ;kinsman/kinswoman + ;we set the relation to be kinsmen if there's any family relation at all. This will get "overwritten" if we discover a more specific relationship + if Actor1.hasFamilyRelationship(Actor2) + if sex == "male" + relation = "kinsman" + else ;female + relation = "kinswoman" + endif + endif + + ;husband/wife + if Actor1.hasAssociation(pSpouse, Actor2) + if sex == "male" + relation = "husband" + else ;female + relation = "wife" + endif + endif + + ;father/mother + if Actor1.hasAssociation(pParentChild, Actor2) + if position == "parent" + if sex == "male" + relation = "father" + else ;female + relation = "mother" + endif + + else ;child + if sex == "male" + relation = "son" + else ;female + relation = "daughter" + endif + endif + endif + + ;brother/sister + if Actor1.hasAssociation(pSiblings, Actor2) + if sex == "male" + relation = "brother" + else ;female + relation = "sister" + endif + endif + + ;uncle/aunt + if Actor1.hasAssociation(pAuntUncle, Actor2) + if position == "parent" + if sex == "male" + relation = "uncle" + else ;female + relation = "aunt" + endif + + else ;child + if sex == "male" + relation = "nephew" + else ;female + relation = "niece" + endif + endif + endif + + ;cousin male/cousin female + if Actor1.hasAssociation(pCousins, Actor2) + if sex == "male" + relation = "cousin male" + else ;female + relation = "cousin female" + endif + endif + + ;boyfriend/girlfriend + if Actor1.hasAssociation(pCourting, Actor2) + if sex == "male" + relation = "boyfriend" + else ;female + relation = "girlfriend" + endif + endif + + return relation +endFunction + +function StartGameTag(ObjectReference FirstPlayer, ObjectReference SecondPlayer, int SecondsToPlay, form CallingFormSelf) + +; debug.trace("WIFunctions StartGameTag(" + FirstPlayer + ", " + SecondPlayer + ", " + SecondsToPlay + ", " + CallingFormSelf + ")") + + WIGamesTag.Stop() + + int bailOutTime = 30 ;wait at most 30 seconds so you don't hold up whatever script is calling this function + int waitingFor = 0 + + bool timeToBailOut = False + + while WIGamesTag.IsRunning() && timeToBailOut == false + utility.wait(1) + waitingFor += 1 +; debug.trace("WIFunctions StartGameTag() waiting for previous WIGamesTag quest to finish stopping. Have been waiting for " + waitingFor + "seconds.") + + if waitingFor >= bailOutTime + timeToBailOut = True +; debug.trace("WIFunctions StartGameTag() have been waiting to long, bailing out. This means this game of tag will not start.", 1) + + EndIf + + EndWhile + + WIGamesTagStart.SendStoryEvent(akRef1 = FirstPlayer, akRef2 = SecondPlayer, aiValue1 = SecondsToPlay) + + +EndFunction + +function updateWIDragonTimer() + ; update timer for when next WI dragon is allowed to appear + WINextDragon.SetValue(GameDaysPassed.GetValue() + WIWaitDragon.GetValue()) + + if MQ305.IsCompleted() + WINextDragon.SetValue(WINextDragon.GetValue() + 3 ) + endif +endFunction + +function startWIDragonKillQuest(Actor Dragon) +; debug.trace("WIFunctions startWIDragonKillQuest(" + Dragon + ")") + WIDragonKilledStart.SendStoryEvent(akRef1 = Dragon) +EndFunction + +function PlayerIsCurrentlyAbsorbingPower(Actor Dragon) +; debug.trace("WIFunctions PlayerIsCurrentlyAbsorbingPower(" + Dragon + ") calling SetFactionRank(WIDragonKilledAbsorbedFaction, 0)") + Dragon.SetFactionRank(WIDragonKilledAbsorbedFaction, 1) ;means "player is currently absorbing - used to conditionalize scene dialogue in WIDragonKilled quest +EndFunction + +function PlayerIsDoneAbsorbingPower(Actor Dragon) +; debug.trace("WIFunctions PlayerIsDoneAbsorbingPower(" + Dragon + ") calling SetFactionRank(WIDragonKilledAbsorbedFaction, 1)") + Dragon.SetFactionRank(WIDragonKilledAbsorbedFaction, 2) ;means "player is done absorbing - used to conditionalize scene dialogue in WIDragonKilled quest +EndFunction + + +function DisallowComplexInteractions(Location LocationToToggle) +{Decrements the keyword data on WIComplexInteractionToggle} + + if LocationToToggle.HasKeyword(WIComplexInteractionToggle) + Float keywordData = LocationToToggle.GetKeywordData(WIComplexInteractionToggle) - 1 + + LocationToToggle.SetKeywordData(WIComplexInteractionToggle, keywordData) + +; debug.trace("WIFunctions DisallowComplexInteractions(" + LocationToToggle + ") decremented keyword data WIComplexInteractionOffToggle to: " + keywordData) + + + Else +; debug.trace(" WARNING: WIFunctions DisallowComplexInteractions(" + LocationToToggle + ") -- keyword WIComplexInteractionOffToggle does not exist on location.", 2) + + EndIf + +EndFunction + + +function DisallowDragons(Location LocationToToggle) +{Decrements the keyword data on WIComplexInteractionToggle} + + if LocationToToggle.HasKeyword(WIDragonsToggle) + Float keywordData = LocationToToggle.GetKeywordData(WIDragonsToggle) - 1 + + LocationToToggle.SetKeywordData(WIDragonsToggle, keywordData) + +; debug.trace("WIFunctions DisallowDragons(" + LocationToToggle + ") decremented keyword data WIDragonsToggle to: " + keywordData) + + + Else +; debug.trace(" WARNING: WIFunctions DisallowDragons(" + LocationToToggle + ") -- keyword WIDragonsToggle does not exist on location.", 2) + + EndIf + +EndFunction + +function AllowComplexInteractions(Location LocationToToggle) +{Increments the keyword data on WIComplexInteractionToggle} + + if LocationToToggle.HasKeyword(WIComplexInteractionToggle) + Float keywordData = LocationToToggle.GetKeywordData(WIComplexInteractionToggle) + 1 + + LocationToToggle.SetKeywordData(WIComplexInteractionToggle, keywordData) + +; debug.trace("WIFunctions AllowComplexInteractions(" + LocationToToggle + ") incremented keyword data WIComplexInteractionOffToggle to: " + keywordData) + + Else +; debug.trace(" WARNING: WIFunctions AllowComplexInteractions(" + LocationToToggle + ") -- keyword WIComplexInteractionOffToggle does not exist on location.", 2) + + EndIf + +EndFunction + + +function AllowDragons(Location LocationToToggle) +{Increments the keyword data on WIComplexInteractionToggle} + + if LocationToToggle.HasKeyword(WIComplexInteractionToggle) + Float keywordData = LocationToToggle.GetKeywordData(WIComplexInteractionToggle) + 1 + + LocationToToggle.SetKeywordData(WIComplexInteractionToggle, keywordData) + +; debug.trace("WIFunctions AllowDragons(" + LocationToToggle + ") incremented keyword data WIComplexInteractionOffToggle to: " + keywordData) + + Else +; debug.trace(" WARNING: WIFunctions AllowDragons(" + LocationToToggle + ") -- keyword WIComplexInteractionOffToggle does not exist on location.", 2) + + EndIf + +EndFunction + +function ShowPlayerRoom(Actor Innkeeper, ObjectReference Bed) +; debug.trace("WIFunctions ShowPlayerRoom(" + Innkeeper + ")") + + WIRentRoomWalkToStart.SendStoryEvent(akRef1 = Innkeeper, akRef2 = Bed) + + +EndFunction + + +bool function RegisterDragonAttack(Location LocationOfDragonAttack, Actor Dragon) + + ;CALLED BY: DragonActorScript, DragonPerchScript, quest fragment scripts attached to WIDragonKilled, WIChangeLocation09 + +; debug.trace("WIFunctions RegisterDragonAttack(" + LocationOfDragonAttack + "," + Dragon + ")") + +; debug.MessageBox("WIFunctions RegisterDragonAttack(" + LocationOfDragonAttack + "," + Dragon + ")") + + bool returnVar + + if LocationOfDragonAttack.HasKeyword(WIDragonAttacked) +; debug.trace("WIFunctions RegisterDragonAttack() Location has WIDragonAttacked keyword, setting data.") + + LocationOfDragonAttack.SetKeywordData(WIDragonAttacked, 1) + returnVar = True + + Else +; debug.trace("WIFunctions RegisterDragonAttack() Location does NOT have WIDragonAttacked keyword, so we are NOT setting data.") + + returnVar = False + + EndIf + + return returnVar + +EndFunction +