cmorgan Posted April 7, 2009 Share Posted April 7, 2009 Starting the main SoA script for Aran, C-ARAN.BCS. A quick reminder - the character's .BCS file is a script. It tells the game engine when it is time (and under what conditions) actions happen. There are all sorts of scripts; here, we are working with the "override script", the highest level. It runs when your NPC is going about his business, stops when he is dead, and generally controls anything you want it to. Side Note: Variable Classes I am using "GLOBAL", "LOCALS", and sometimes "AREA" as designated scripts. I am also using both RealSetGlobalTimer() and SetGlobalTimer(). BioWare was inconsistent in usage, and folks have different opinions on this topic (just like BioWare used LOCALS and Interact() to place lots of stuff on the banter file, while modern mods avoid putting anything that you really want to specifically fire at a precise moment on the J file and use Dialog/StartDialogNoSet() ), but I am using the following internal designations, which other folks may not agree with: LOCALS = stored on the .cre; only use when nothing else is going to cross reference it. For example, if I have an interjection into a dialog I will not be using as a flag for further comment, or if I have a minor talk that I am not going to worry about follow up on, like the first time the party kills an Ettercap and he wants to comment on it. GLOBAL = Lovetalks, Friendship talks, Quest variables, and anything I might want to crossreference later. For example, if I have Aran flirt while drunk, and I might want to reference it with another NPC or the PC. Most material fits this pattern of usage for me, and is really the default condition. RealGlobalTimerExpired() || RealSetGlobalTimer() will always be GLOBAL and will be for anything used to space out dialog or actions in real time for players GlobalTimerExpired() || SetGlobalTimer() will always be GLOBAL and will be for anything used to temporarily delay dialog or actions in game time for players According to the IESDP, the only timer check that will evaluate true if it has EITHER never been set OR has expired is !GlobalTimerNotExpired("myVar","GLOBAL")So on the very vew things that start from 0 instead of being set to 1 by a 'kick-off" block, I will use this in conjunction with SetGlobalTimer(). Most things, though, will start with an initialization in either dialog or .bcs setting a timer, so most of the time RealGlobalTimerExpired() or GlobalTimerExpired() will do fine. AREA = not if I can possibly help it. edit: this stuff looks so pretty in the highlighter, and so plain without. But I am not messing up code with colorized bbcode for the rest of this. I am going to comment the code instead. /* CONTENTS: */ /* Timers: * [REAL TIME] c-aranfriendtimer | c-aranromtimer * * [GAME TIME] c-aransmalltalk | * * Variables: * [GLOBAL] c-aranfriendbg2 | c-aranmatch | c-aranromance | c-aranbg2rom | c-aranvamped | c-silencearan | c-arandrunk * * [LOCALS] c-aranpckeep | c-aranlich | c-aranshadelord | c-arandragon | c-aranbasilisk | c-aranettercap | c-arangolem * c-aranzombie | c-aranworkbod | c-aranworkaran | c-aranphaere | c-aranslaver | c-aranleader | c-aranpctired | c-aranoghma * c-aranilmater | c-aranhelm | c-aranlath | c-aranumberlee | c-aranwaukeen | c-aranoldbat * Resources: * [SOUND] C-ARANFT | C-ARANLT | C-ARANH * */ /* FRIEND TALKS */ * OK let's start with the Friend Talks. The idea here is to set the friendtalks up on a BCS <> DLG "bounce", so * 1. set the talk variable to 1 and set a timer. * 2. set a block that sees that the timer has expired, and initiates dialog. * 3. the game looks for the variable (1), and sees the dialog, and fires it. * 4. The dialog line advances the variable to (2), and sets a new timer. * 5. The BCS here looks for the timer to expire and the even variable (2), advancing to (3) when the timer expires * Then when it sees the conditions are right, repeat sequence from 3. */ /* Friend Talks Sequence */ /* Friend Talks Setup */ IF Global("c-aranfriendbg2","GLOBAL",0) // Not evaluated true yet InParty(Myself) // Aran is here !StateCheck(Myself,CD_STATE_NOTVALID) // Aran is ok !StateCheck(Player1,CD_STATE_NOTVALID) // Player1 is ok THEN RESPONSE #100 // 100% of the time SetGlobal("c-aranfriendbg2","GLOBAL",1) // set up SoA_FT_1 RealSetGlobalTimer("c-aranfriendtimer","GLOBAL",600) // Minimum Real Time until SoA_FT_1 END /* Aran's FriendTalks Aim, c-aranfriendbg2, ARAN_FTT */ /* This block takes the even variables set in dialog, and advances them to the odd */ IF GlobalLT("c-aranfriendbg2","GLOBAL",32) // shuts down sequence when finished RealGlobalTimerExpired("c-aranfriendtimer","GLOBAL") // Timer Expired !Global("Chapter","GLOBAL",5) // Not in Underdark - specialized talks for that OR(15) Global("c-aranfriendbg2","GLOBAL",2) // set up SoA_FT_2 Global("c-aranfriendbg2","GLOBAL",4) // set up SoA_FT_3 Global("c-aranfriendbg2","GLOBAL",6) // set up SoA_FT_4 Global("c-aranfriendbg2","GLOBAL",8) // set up SoA_FT_5 Global("c-aranfriendbg2","GLOBAL",10) // set up SoA_FT_6 Global("c-aranfriendbg2","GLOBAL",12) // set up SoA_FT_7 Global("c-aranfriendbg2","GLOBAL",14) // set up SoA_FT_8 Global("c-aranfriendbg2","GLOBAL",16) // set up SoA_FT_9 Global("c-aranfriendbg2","GLOBAL",18) // set up SoA_FT_10 Global("c-aranfriendbg2","GLOBAL",20) // set up SoA_FT_11 Global("c-aranfriendbg2","GLOBAL",22) // set up SoA_FT_12 Global("c-aranfriendbg2","GLOBAL",24) // set up SoA_FT_13 Global("c-aranfriendbg2","GLOBAL",26) // set up SoA_FT_14 Global("c-aranfriendbg2","GLOBAL",28) // set up SoA_FT_15 Global("c-aranfriendbg2","GLOBAL",30) // set up SoA_FT_16 THEN RESPONSE #100 IncrementGlobal("c-aranfriendbg2","GLOBAL",1) // move up from even to odd END /* Aran's FriendTalks Fire, c-aranfriendbg2, ARAN_FTT */ /* This block takes the odd variables set by the last block, and tries to fire them off. */ IF GlobalLT("c-aranfriendbg2","GLOBAL",32) // shuts down sequence when finished RealGlobalTimerExpired("c-aranfriendtimer","GLOBAL") // Timer Expired !Global("Chapter","GLOBAL",5) // Not in Underdark - specialized talks for that InParty(Myself) // Aran is here !StateCheck(Myself,CD_STATE_NOTVALID) // Aran is ok !StateCheck(Player1,CD_STATE_NOTVALID) // Player1 is ok CombatCounter(0) // Not in combat !See([ENEMY]) // Can't see any enemies OR(16) Global("c-aranfriendbg2","GLOBAL",1) // fire SoA_FT_1 Global("c-aranfriendbg2","GLOBAL",3) // fire SoA_FT_2 Global("c-aranfriendbg2","GLOBAL",5) // fire SoA_FT_3 Global("c-aranfriendbg2","GLOBAL",7) // fire SoA_FT_4 Global("c-aranfriendbg2","GLOBAL",9) // fire SoA_FT_5 Global("c-aranfriendbg2","GLOBAL",11) // fire SoA_FT_6 Global("c-aranfriendbg2","GLOBAL",13) // fire SoA_FT_7 Global("c-aranfriendbg2","GLOBAL",15) // fire SoA_FT_8 Global("c-aranfriendbg2","GLOBAL",17) // fire SoA_FT_9 Global("c-aranfriendbg2","GLOBAL",19) // fire SoA_FT_10 Global("c-aranfriendbg2","GLOBAL",21) // fire SoA_FT_11 Global("c-aranfriendbg2","GLOBAL",23) // fire SoA_FT_12 Global("c-aranfriendbg2","GLOBAL",25) // fire SoA_FT_13 Global("c-aranfriendbg2","GLOBAL",27) // fire SoA_FT_14 Global("c-aranfriendbg2","GLOBAL",29) // fire SoA_FT_15 Global("c-aranfriendbg2","GLOBAL",31) // fire SoA_FT_16 THEN RESPONSE #100 PlaySong(0) // play a blank reference, stoping the soundtrack PlaySound("C-ARANFT") // play a .wav or .wavc file StartDialogueNoSet(Player1) // Yo, we are talkin', here... END /* ROMANCE TALKS */ /* Romance Match and Initiation (He is not picky...) * One new thing here - Aran is ok if a friend switches genders - * but not so much on the romance side. So, we add a blocking variable * to make sure nothing progresses while that silly Girdle is in place. * He can have some special lines to play during the FT sequence on that. */ IF Global("c-aranmatch","GLOBAL",0) // Not evaluated InParty(Myself) // Aran is here !StateCheck(Myself,CD_STATE_NOTVALID) // Aran is ok !StateCheck(Player1,CD_STATE_NOTVALID) // Player1 is ok Gender(Player1,FEMALE) // Player1 is female !HasItemEquiped("belt05",Player1) // Girdle of sex change not on Player1 THEN RESPONSE #100 // 100% of the time SetGlobal("c-aranmatch","GLOBAL",1) // Matched SetGlobal("c-aranromance","GLOBAL",1) // Aran is interested RealSetGlobalTimer("c-aranromtimer","GLOBAL",1200) // Minimum Real Time until first LT SetGlobal("c-aranbg2rom","GLOBAL",1) // Tee up SoA_LT_1 END /* LOVE TALKS */ /* Romance Talks Sequence */ /* Aran's Romance LoveTalks Aim, c-aranbg2rom, ARAN_LTT */ /* This block takes the even variables set in dialog, and advances them to the odd */ IF GlobalLT("c-aranbg2rom","GLOBAL",32) // shuts down sequence when finished RealGlobalTimerExpired("c-aranromtimer","GLOBAL") // Timer Expired !Global("Chapter","GLOBAL",5) // Not in Underdark - specialized talks for that !HasItemEquiped("belt05",Player1) // Not using Girdle of sex change OR(15) Global("c-aranbg2rom","GLOBAL",2) // set up SoA_LT_2 Global("c-aranbg2rom","GLOBAL",4) // set up SoA_LT_3 Global("c-aranbg2rom","GLOBAL",6) // set up SoA_LT_4 Global("c-aranbg2rom","GLOBAL",8) // set up SoA_LT_5 Global("c-aranbg2rom","GLOBAL",10) // set up SoA_LT_6 Global("c-aranbg2rom","GLOBAL",12) // set up SoA_LT_7 Global("c-aranbg2rom","GLOBAL",14) // set up SoA_LT_8 Global("c-aranbg2rom","GLOBAL",16) // set up SoA_LT_9 Global("c-aranbg2rom","GLOBAL",18) // set up SoA_LT_10 Global("c-aranbg2rom","GLOBAL",20) // set up SoA_LT_11 Global("c-aranbg2rom","GLOBAL",22) // set up SoA_LT_12 Global("c-aranbg2rom","GLOBAL",24) // set up SoA_LT_13 Global("c-aranbg2rom","GLOBAL",26) // set up SoA_LT_14 Global("c-aranbg2rom","GLOBAL",28) // set up SoA_LT_15 Global("c-aranbg2rom","GLOBAL",30) // set up SoA_LT_16 THEN RESPONSE #100 IncrementGlobal("c-aranbg2rom","GLOBAL",1) END /* Aran's Romance LoveTalks Fire, c-aranbg2rom, ARAN_LTT */ /* This block takes the odd variables set by the last block, and tries to fire them off. */ IF GlobalLT("c-aranbg2rom","GLOBAL",32) // shuts down sequence when finished RealGlobalTimerExpired("c-aranromtimer","GLOBAL") // Timer Expired !Global("Chapter","GLOBAL",5) // Not in Underdark - specialized talks for that !HasItemEquiped("belt05",Player1) // Not using Girdle of sex change CombatCounter(0) // Not in combat !See([ENEMY]) // Can't see any enemies OR(16) Global("c-aranbg2rom","GLOBAL",1) // fire SoA_LT_1 Global("c-aranbg2rom","GLOBAL",3) // fire SoA_LT_2 Global("c-aranbg2rom","GLOBAL",5) // fire SoA_LT_3 Global("c-aranbg2rom","GLOBAL",7) // fire SoA_LT_4 Global("c-aranbg2rom","GLOBAL",9) // fire SoA_LT_5 Global("c-aranbg2rom","GLOBAL",11) // fire SoA_LT_6 Global("c-aranbg2rom","GLOBAL",13) // fire SoA_LT_7 Global("c-aranbg2rom","GLOBAL",15) // fire SoA_LT_8 Global("c-aranbg2rom","GLOBAL",17) // fire SoA_LT_9 Global("c-aranbg2rom","GLOBAL",19) // fire SoA_LT_10 Global("c-aranbg2rom","GLOBAL",21) // fire SoA_LT_11 Global("c-aranbg2rom","GLOBAL",23) // fire SoA_LT_12 Global("c-aranbg2rom","GLOBAL",25) // fire SoA_LT_13 Global("c-aranbg2rom","GLOBAL",27) // fire SoA_LT_14 Global("c-aranbg2rom","GLOBAL",29) // fire SoA_LT_15 Global("c-aranbg2rom","GLOBAL",31) // fire SoA_LT_16 THEN RESPONSE #100 PlaySong(0) PlaySound("C-ARANLT") StartDialogueNoSet(Player1) END /* OK, now on to some fun blocks to play with. These are things Aran can blather on about. */ /* TALKS, FLOATING AND SMALL */ /* Covers both specific reactions, floaters, and any smalltalk reactions (could also be * called "after-the-fact interjections") */ /* After-Vampification Talk, Canonical, 2nd Class. */ IF !InParty(Myself) Global("c-aranvamped","GLOBAL",4) THEN RESPONSE #100 SetGlobal("c-aranvamped","GLOBAL",5) StartDialogueNoSet(Player1) END /* Stronghold Commentary */ /* PC Owns Keep */ IF Global("PCKeepOwner","GLOBAL",1) Global("c-silencearan","GLOBAL",0) // PID - set silencer Global("c-aranpckeep","LOCALS",0) InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) CombatCounter(0) !See([ENEMY]) THEN RESPONSE #100 SetGlobal("c-aranpckeep","LOCALS",1) StartDialogueNoSet(Player1) END /* Drunk Talks (incorporates Flirts if gender and romance variables set) */ /* Using GLOBAL here so it can influence friendtalks */ IF GlobalLT("c-arandrunk","GLOBAL",6) // shuts down sequence when finished InParty(Myself) CheckStatGT(Myself,50,INTOXICATION) // Whoot - the room is moving about too much OR(12) AreaCheck("AR0313") // Sea's Bounty AreaCheck("AR0406") // Copper Coronet AreaCheck("AR0509") // Five Flagons AreaCheck("AR0522") // Five Flagons (Stronghold) AreaCheck("AR0704") // Mithrest Inn AreaCheck("AR1105") // Umar Inn AreaCheck("AR1602") // The Vulgar Monkey AreaCheck("AR2010") // Vyatri's Pub, Trademeet AreaCheck("AR0709") // Den of the Seven Vales 1st Floor AreaCheck("AR0513") // Calbor's Inn at Bridge District 1st Floor AreaCheck("AR0021") // Crooked Crane 1st Floor AreaCheck("AR1602") // Brynnlaw's Inn OR(3) Global("c-arandrunk","GLOBAL",0) Global("c-arandrunk","GLOBAL",2) Global("c-arandrunk","GLOBAL",4) !StateCheck(Player1,CD_STATE_NOTVALID) CombatCounter(0) !See([ENEMY]) THEN RESPONSE #100 IncrementGlobal("c-arandrunk","GLOBAL",1) END IF GlobalLT("c-arandrunk","GLOBAL",6) // shuts down sequence when finished !GlobalTimerNotExpired("c-aransmalltalk","GLOBAL") // Timer (game-time) has never been set or has expired OR(12) AreaCheck("AR0313") // Sea's Bounty AreaCheck("AR0406") // Copper Coronet AreaCheck("AR0509") // Five Flagons AreaCheck("AR0522") // Five Flagons (Stronghold) AreaCheck("AR0704") // Mithrest Inn AreaCheck("AR1105") // Umar Inn AreaCheck("AR1602") // The Vulgar Monkey AreaCheck("AR2010") // Vyatri's Pub, Trademeet AreaCheck("AR0709") // Den of the Seven Vales 1st Floor AreaCheck("AR0513") // Calbor's Inn at Bridge District 1st Floor AreaCheck("AR0021") // Crooked Crane 1st Floor AreaCheck("AR1602") // Brynnlaw's Inn CombatCounter(0) // Not in combat !See([ENEMY]) // Can't see any enemies OR(3) Global("c-arandrunk","GLOBAL",1) Global("c-arandrunk","GLOBAL",3) Global("c-arandrunk","GLOBAL",5) THEN RESPONSE #100 PlaySong(0) PlaySound("C-ARANH") StartDialogueNoSet(Player1) END /* Monster Reactions */ /* Commenting on some Monster Encounters, Working for The Man/Undead */ IF !GlobalTimerNotExpired("c-aransmalltalk","GLOBAL") // Timer (game-time) has never been set or has expired Global("c-silencearan","GLOBAL",0) // a PID - set "silencer" for folks who hate unsolicited comments InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) OR(9) Global("c-aranlich","LOCALS",1) Global("c-aranshadelord","LOCALS",1) Global("c-arandragon","LOCALS",1) Global("c-aranbasilisk","LOCALS",1) Global("c-aranettercap","LOCALS",1) Global("c-arangolem","LOCALS",1) Global("c-aranzombie","LOCALS",1) Global("c-aranworkbod","LOCALS",1) Global("c-aranworkaran","LOCALS",1) THEN RESPONSE #100 SetGlobalTimer("c-aransmalltalk","GLOBAL",300) // spaces comments StartDialogNoSet(Player1) END /* For catching general objects without regard to DVs, we can use a general catch all using the .ids entries - * [EA.GENERAL.RACE.CLASS]. An entry of 0 in a field will match any value. * For example: [ENEMY.0.0.MAGE] specifies all creatures that are enemies of the party, any general category, any race, mages. * Amber uses these to good effect, so I started by borrowing from that code, then readjusting and extending - */ /* Liches Are Scary (Darios) */ IF Global("c-silencearan","GLOBAL",0) Global("c-aranlich","LOCALS",0) OR(2) Killed([0.0.LICH]) Killed([0.0.DEMILICH]) InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranlich","LOCALS",1) END /* Shade Lord (Darios) */ IF Killed([0.UNDEAD.SHADOW.SHADOW.0.FEMALE]) // Shade Lord Global("c-silencearan","GLOBAL",0) Global("c-aranshadelord","LOCALS",0) OR(2) AreaCheck("AR1400") // Temple ruins AreaCheck("AR1404") // Temple ruins restored InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranshadelord","LOCALS",1) END /* Aran Dragon-Slayer (Darios) */ IF Killed([0.0.DRAGON]) Global("c-silencearan","GLOBAL",0) Global("c-arandragon","LOCALS",0) !AreaCheck("AR2102") // Adalon's cave InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-arandragon","LOCALS",1) END /* Basilisk Baiting */ IF Killed([0.0.BASILISK]) Global("c-silencearan","GLOBAL",0) Global("c-aranbasilisk","LOCALS",0) InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranbasilisk","LOCALS",1) END /* Poisonous Cloakwood Ettercaps */ IF Killed([0.0.ETTERCAP]) Global("c-silencearan","GLOBAL",0) Global("c-aranettercap","LOCALS",0) InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranettercap","LOCALS",1) END /* Golems are Big Boys */ IF Killed([0.0.GOLEM]) Global("c-silencearan","GLOBAL",0) Global("c-arangolem","LOCALS",0) InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-arangolem","LOCALS",1) END /* Zombies: Looks Like Me After A Night On The Town */ IF Killed([0.0.ZOMBIE]) Global("c-silencearan","GLOBAL",0) Global("c-aranzombie","LOCALS",0) InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranzombie","LOCALS",1) END /* Real Great Employer, buddy. Someone pass me the Daystar. */ IF Global("WorkingForBodhi","GLOBAL",1) Global("c-silencearan","GLOBAL",0) Global("c-aranworkbod","LOCALS",0) InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranworkbod","LOCALS",1) END /* Real Great Employer, buddy. But at least he's not undead. I think. */ IF Global("WorkingForAran","GLOBAL",1) Global("c-silencearan","GLOBAL",0) Global("c-aranworkaran","LOCALS",1) InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranworkaran","LOCALS",1) END /* Commenting on Phaerie, Leader, Slaver Procession, and a few more */ IF !GlobalTimerNotExpired("c-aransmalltalk","GLOBAL") // Timer (game-time) has never been set or has expired Global("c-silencearan","GLOBAL",0) // a PID - set "silencer" for folks who hate unsolicited comments OR(4) Global("c-aranphaere","LOCALS",1) Global("c-aranslaver","LOCALS",1) Global("c-aranleader","LOCALS",1) Global("c-aranpctired","LOCALS",1) InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobalTimer("c-aransmalltalk","GLOBAL",300) // spaces comments StartDialogNoSet(Player1) END /* Phaere is a hawt chick (male PC); is no good for you (female PC); better not have touched you (Romance) */ IF InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) OR(2) Global("PhaereInnuendo","GLOBAL",2) Global("PhaereInnuendo","GLOBAL",3) Global("c-aranphaere","LOCALS",0) THEN RESPONSE #100 SetGlobal("c-aranphaere","LOCALS",1) END /* Slums Slavers (Darios, extended) */ IF AreaCheck( <<HERE>> ) Global("c-aranslaver","LOCALS",0) See("SlumsSlaver2") See("SlumsSlaver3") See("SlumsSlave1") InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranslaver","LOCALS",1) END /* Setting Aran as Leader */ IF Global("c-aranleader","LOCALS",0) Name("c-aran",Player1Fill) InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranleader","LOCALS",1) END /* You look dead on your feet */ IF CheckStatGT(Player1,5,FATIGUE) Global("c-aranpctired","LOCALS",0) InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranpctired","LOCALS",1) END /* Temple Comments, Only If Not A Cleric (even minimal training would keep him from starting a holy fight) Firing */ IF !Class(Myself,CLERIC_ALL) !GlobalTimerNotExpired("c-aransmalltalk","GLOBAL") // Timer (game-time) has never been set or has expired Global("c-silencearan","GLOBAL",0) // a PID - set "silencer" for folks who hate unsolicited comments OR(4) Global("c-aranoghma","LOCALS",1) Global("c-aranilmater","LOCALS",1) Global("c-aranhelm","LOCALS",1) Global("c-aranlath","LOCALS",1) // Global("c-arantalos","LOCALS",1) // skipped because of quest Global("c-aranumberlee","LOCALS",1) Global("c-aranwaukeen","LOCALS",1) InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobalTimer("c-aransmalltalk","GLOBAL",300) // spaces comments StartDialogNoSet(Player1) END /* Temple Comments, Only If Not A Cleric (even minimal training would keep him from starting a holy fight) */ IF !Class(Myself,CLERIC_ALL) Global("c-silencearan","GLOBAL",0) Global("c-aranoghma","LOCALS",0) AreaCheck("AR0319") // Temple of Oghma InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranoghma","LOCALS",1) END IF !Class(Myself,CLERIC_ALL) Global("c-silencearan","GLOBAL",0) Global("c-aranilmater","LOCALS",0) OR(2) AreaCheck("AR0408") // Temple of Ilmater AreaCheck("AR0703") // Temple of Ilmater InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranilmater","LOCALS",1) END IF !Class(Myself,CLERIC_ALL) Global("c-silencearan","GLOBAL",0) Global("c-aranhelm","LOCALS",0) OR(2) AreaCheck("AR0512") // Temple of Helm AreaCheck("AR0901") // Temple of Helm InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranhelm","LOCALS",1) END IF !Class(Myself,CLERIC_ALL) Global("c-silencearan","GLOBAL",0) Global("c-aranlath","LOCALS",0) AreaCheck("AR0902") // Temple of Lathander InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranlath","LOCALS",1) END IF !Class(Myself,CLERIC_ALL) Global("c-silencearan","GLOBAL",0) Global("c-arantalos","LOCALS",0) AreaCheck("AR0904") // Temple of Talos InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-arantalos","GLOBAL",1) END IF !Class(Myself,CLERIC_ALL) Global("c-silencearan","GLOBAL",0) Global("c-aranumberlee","LOCALS",0) AreaCheck("AR1604") // Temple of Umberlee InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranumberlee","LOCALS",1) END IF !Class(Myself,CLERIC_ALL) Global("c-silencearan","GLOBAL",0) Global("c-aranwaukeen","LOCALS",0) OR(2) AreaCheck("AR1010") // Temple of Waukeen AreaCheck("AR2008") // Temple of Waukeen InParty(Myself) !StateCheck(Myself,CD_STATE_NOTVALID) !StateCheck(Player1,CD_STATE_NOTVALID) THEN RESPONSE #100 SetGlobal("c-aranwaukeen","LOCALS",1) END Posting the related dialogs in Interjections for Aran Link to comment
erik Posted April 8, 2009 Share Posted April 8, 2009 About the fatigue talk; combat penalties and fatigue icon appears at fatigue 7. So a bit early? (though Full Plate modifies them to appear at 6) Link to comment
cmorgan Posted April 8, 2009 Author Share Posted April 8, 2009 Oh, darn, good catch - will edit to 7, as I want it to fire when the in-game fatigue comes in. I lifted this idea directly from Darios, and I expect his (and Miera's) intention was to have a little bit of "sixth sense" with a Tiefling, but Aran shouldn't be that sensitive. Thanks! Link to comment
Jarno Mikkola Posted April 8, 2009 Share Posted April 8, 2009 OK, that's nice and all, but can you tell me what's the difference of all the script attached to the creature file... you used the "override script" and told what it basically does, but what the other do? PS: the whole thing won't work cause of the end of this line: FRIEND TALKS */ Link to comment
cmorgan Posted April 8, 2009 Author Share Posted April 8, 2009 Whoa, missed that - thanks - I'll take that end-block-comment out so it works! As for the scripts, well, there are two things - scripts and "scope of variables sorting" (there has got to be a better way of describing this). Variables, as reported in the IESDP, are sorted into global (between-creature communication) locals ("This allows for several creatures to use the same script (with the same variable names) as the value assigned to variables are for each creature." - i.e., I can set Aran to have "HaveKissedPCThisManyTimes" and also have the same variable assigned to another NPC, say Ilyos, and they can track different numbers) and area (which is seen by everything, but can be set to different values in each area). The use of LOCALS is the pat that gets folks dividing up over what is "good coding". In BG1, the LOCALS variable is stored in the game session, and at no other time. So for BG1, LOCALS means "one shot, and if you hit ctr-r it probably goes away". In BG2, the LOCALS are stored better, so that problem goes away, but the creature who sets the variable is the ony one who can reference it - if I set c-arankissedthepc = 1 and store it as a LOCALS, no one but Aran can "see" that variable, so if I want it to triger someone else to comment if he has kissed her 5 times, nope - can't do it by referecing. BioWare coded all the BG2 LTs I have seen this way, I am assuming because they felt LTs were private one-on-one conversations nop-one else in the party wuld ever need to reference (a wild and unsupported guess on my part). I have no data on whether it makes any difference to the game processing speed if you set hundreds of GLOBAL vs hundreds of LOCAL vs hundreds of AREA. I have always used GLOBAL almost exclusively. But my "better safe than sorry" on Aran is to move closer to BioWare and follow SConrad's notes on use of LOCALS, spreading out the number of times I use each a bit more. Not a particularly scholarly /tested approach on my part, but it sounds good, so why not? As for the scripts, there are several that work at different levels. This entry has the data, but you really wan to hop over to PPG and take a look at the big "how scripts work' tutorial post - I'll try to look it up when I get home. The summary (as I understand it) is that it works kind of like a decision tree - override script is checked for smething that is valid, and if nothing fires, the engine moves on to the next on down the line to check. So 0 OVERRIDE 1 AREA 2 SPECIFICS 4 CLASS 5 RACE 6 GENERAL 7 DEFAULT where c-aran.bs is the "override" that will have all the custom stuff. Other scripts, like WTASIGHT.BCS, etc., fill in the remaining scripts and provide actions specific to those functions. I guess technically that means you could create custom scripts for all of these levels. In practice, everyone seems to dump everything (including combat scrip materials) into both Joinable and Non-Joinable NPCs "override" scripts. Link to comment
Ardanis Posted April 8, 2009 Share Posted April 8, 2009 !GlobalTimerNotExpired() - it's generally used in combat scripts, where you can have multiple IF !GlobalTimerNotExpired("one_round","locals") HaveSpell(WIZARD_SPELL) THEN RESPONSE #100 SetGlobalTimer("one_round","locals",6) Spell(Target,WIZARD_SPELL) END blocks, instead of doubling their amount due to uncertainty whether or not the timer had been already set. So, basically there's no much benefit from using it in normal scripts, it will save few blocks at most. Still better, but probably not enough to compensate the confusion of novice modder, should they be reading this. In practice, everyone seems to dump everything (including combat scrip materials) into both Joinable and Non-Joinable NPCs "override" scripts.That's very bad to do, and it was a case in Xulaye. First, combat usually weights quite a bit, second, it can mess with player's directions. The best way is to have a trigger in normal script with checks for a need to go hostile, then switch to a pure combat one, should such a need occur. Link to comment
cmorgan Posted April 8, 2009 Author Share Posted April 8, 2009 Good points - at most, it will save perhaps 4 blocks total, since I am using medium blocks of OR(#) to trigger dialog instead of a long list of small follow-up SDNS() blocks. I am not convinced I am saving much by doing that, either. The combat script is a point I think I'd better make pretty clearly when we get to that. It also leads us to the side note that somewhere in here we might want to poke at stuff like ANOMEN.BCS vs ANOM25.BCS vs. ANOMEND.BCS vs. ANOMX.BCS [when we get to it, the reminder it is set manually IF Global("AnomenFinalFight","GLOBAL",1) Global("HopToItAnomen","LOCALS",0) THEN RESPONSE #100 SetGlobal("HopToItAnomen","LOCALS",1) SetDialog("") ChangeAIScript("anomx",SPECIFICS) ChangeAIScript("",DEFAULT) ChangeAIScript("useitem",GENERAL) ChangeEnemyAlly(Myself,GOODBUTBLUE) END vs. PRIEST1.BCS vs. WDASIGHT.BCS as I note some mods like Saerileth copy this "out of party combat/cutscene script" and others don't. Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.