Skip to content

RE: Clone a PC and Set it to Use the Bioware AI

[Deleted User][Deleted User] Posts: 0
edited May 2020 in Builders - Scripting
I recently made an area that has the PC fight an evil clone of themselves. I found that the PC clone only seemed to use melee attacks and ignored its spellcasting.

Thanks to the new SetEventScript function, I created this function to overcome this apparent limitation. Now the PC clone can be setup to use various XP2 switches to toggle behavior such as 100% chance to use spells

void ps_SetCreatureEventScripts(object oCreature, string sBlock = "",
                                                  string sDamage = "",
                                                  string sDeath = "",
                                                  string sConv = "",
                                                  string sDisturb = "",
                                                  string sCombat = "",
                                                  string sHeart = "",
                                                  string sAttack = "",
                                                  string sNotice = "",
                                                  string sRest = "",
                                                  string sSpawn = "",
                                                  string sSpell = "",
                                                  string sUser = "" )
{
    // Set the event scripts
    if (sBlock != "" ) SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, sBlock);
    if (sDamage != "" ) SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED, sDamage);
    if (sDeath != "" ) SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DEATH, sDeath);
    if (sConv != "" ) SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, sConv);
    if (sDisturb != "" ) SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED, sDisturb);
    if (sCombat != "" ) SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, sCombat);
    if (sHeart != "" ) SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, sHeart);
    if (sAttack != "" ) SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, sAttack);
    if (sNotice != "" ) SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE, sNotice);
    if (sRest != "" ) SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_RESTED, sRest);
    if (sSpawn != "" ) SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, sSpawn);
    if (sSpell != "" ) SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, sSpell);
    if (sUser != "" ) SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT, sUser);
}


Here's the function in the block of code I use to create the doppleganger:
		object oPC = GetLastUsedBy();
                
		// Create the doppleganger at the spawn location
                location lSpawn = GetLocation(GetWaypointByTag("WP_SPAWN_CLONE"));
                object oSpawn = CreateDoppleganger(oPC, lSpawn);
                ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_1), lSpawn);

                // Set the event scripts for the doppleganger - moved to CreateDoppleganger function
                //ps_SetCreatureEventScripts(oSpawn, "x2_def_onblocked",
                //                                  "x2_def_ondamage",
                //                                   "x2_def_ondeath",
                //                                   "x2_def_onconv",
                //                                   "x2_def_ondisturb",
                //                                   "x2_def_endcombat",
                //                                   "x2_def_heartbeat",
                //                                   "x2_def_attacked",
                //                                   "x2_def_percept",
                //                                   "x2_def_rested",
                //                                   "x2_def_spawn",
                //                                   "x2_def_spellcast",
                //                                   "x2_def_userdef" );

                // Flag for AI spell use
                if (ps_GetIsArcaneCaster(oSpawn) || ps_GetIsDivineCaster(oSpawn) )
                {
                    if (GetLevelByClass(CLASS_TYPE_SORCERER, oPC) || GetLevelByClass(CLASS_TYPE_WIZARD, oPC) )
                    {
                        SetLocalInt(oSpawn, "X2_L_BEH_MAGIC", 100);
                    }
                    else
                    {
                        SetLocalInt(oSpawn, "X2_L_BEH_MAGIC", 50);
                    }
                }
                else
                {
                    AssignCommand(oSpawn, ActionAttack(oPC));
                }


ps_GetIsArcaneCaster() and ps_GetIsDivineCaster() are two other custom functions - they just check for levels in spellcasting classes.
Post edited by [Deleted User] on

Comments

  • By request - the CreateDoppleganger function...
    object ps_CreateDoppleganger(object oPC, location lSpawn)
    {
        object oClone = CopyObject(oPC, lSpawn);
        ChangeToStandardFaction(oClone, STANDARD_FACTION_HOSTILE);
    
        // Make the clone chaotic evil
        AdjustAlignment(oClone, ALIGNMENT_EVIL, 100);
        AdjustAlignment(oClone, ALIGNMENT_CHAOTIC, 100);
    
        // Set the clone to use the XP2 AI
        // Note: using a custom OnDeath event to prevent the clone from dropping
        // duplicates of the PC's inventory - supposed to be a punishment, not a
        // reward.
        ps_SetCreatureEventScripts(oClone, "x2_def_onblocked",
                                           "x2_def_ondamage",
                                           "x0_deck_clonedth",
                                           "x2_def_onconv",
                                           "x2_def_ondisturb",
                                           "x2_def_endcombat",
                                           "x2_def_heartbeat",
                                           "x2_def_attacked",
                                           "x2_def_percept",
                                           "x2_def_rested",
                                           "x2_def_spawn",
                                           "x2_def_spellcast",
                                           "x2_def_userdef" );
        return oClone;
    }
    
  • PaphjortPaphjort Member Posts: 25
    thx for posting this, I can find a use for it. :)
    /Pap
  • I fixed the OP because, as shown in my posting of the CreateDoppleganger function code, I had moved the event script assignment to that function since posting the original code blocks.
Sign In or Register to comment.