Skip to content

I need a script (puking mummy/zombie)

I have some mummies in my mod that have creeping doom. They currently cast the spell.

I would like them to "puke" the spell instead. Either once per creature or for a boss type once/turn.

I was doing some digging for VFX and I think this might work if followed by the creeping doom spell in the location range of the puke: VFX_COM_CHUNK_YELLOW_SMALL, VFX_COM_CHUNK_YELLOW_MEDIUM


Any scripters out there able to take this on for me?

Comments

  • CalgacusCalgacus Member Posts: 273
    edited September 2018
    How do you have the mummies cast the spell? Just as a special ability? I was trying this out on a zombie but so far I don't know how to prevent the zombies cast-spell animation from playing before any puke animation/vfx happens. I'm going to guess this will require an extra entry in spells.2da to add a copy of the creeping doom line and make the needed changes to the animations played. Are you OK with having a new line in your spells.2DA?
  • TarotRedhandTarotRedhand Member Posts: 1,481
    @Calgacus One work around would be to create an invisible placeable next to the zombie and have it cast the spell. That gets rid of the spell animation. Destroy the invisible placeable afterwards.

    TR
  • QuilistanQuilistan Member Posts: 177
    currently my mummies just use the special ability, but I would like it to fire via a heartbeat, combatroundend, or onphysicalattack script. I am not sure which would be best yet? I would only need the creature to fire it once really. Though a boss being able to "reload" the event could be a nice dimension.

    I am hoping for: a vomit sound, then an acid bolt or spray (not sure which would look best?), terminating with the chunky effect and the creeping doom spell to fire at that location.
  • CalgacusCalgacus Member Posts: 273
    edited September 2018
    Here is a rough version - so far it does not play the sound and I'm not sure if it counts as an action:
    Make this script and name it crpdoom_effect
    void main() { //cast creeping doom effect with custom head animation object ochar = OBJECT_SELF; if(ochar == GetLastAttacker(OBJECT_SELF)){ SpeakString("i attacked myself!", TALKVOLUME_SHOUT); return; } // maybe you want it to only fire if attacked by a PC? if(!GetIsPC(GetLastAttacker(OBJECT_SELF))){ SpeakString("attacked by monster!", TALKVOLUME_SHOUT); return; } int time = GetTimeSecond()+(GetTimeMinute()*60)+(GetTimeHour()*3600); if(GetCalendarDay()>1){ time = time + ((GetCalendarDay()-1)*(24*3600)); } if( GetCalendarMonth()>1){ time = time + ((GetCalendarMonth()-1)*(24*3600*31)); } time = time + (GetCalendarYear()*(24*3600*31*12)); SpeakString("time == " + IntToString(time), TALKVOLUME_SHOUT); int lasttime = GetLocalInt(OBJECT_SELF,"crpdoom_time"); SpeakString("lasttime == " + IntToString(lasttime), TALKVOLUME_SHOUT); int nDuration = 1; if( (time - lasttime) < ( (6*nDuration)+12) ) { SpeakString("time diff == "+ IntToString(time - lasttime), TALKVOLUME_SHOUT); SpeakString("too soon to cast creeping doom effect again!", TALKVOLUME_SHOUT); return; } SetLocalInt(OBJECT_SELF, "crpdoom_time", time); SpeakString("casting creeping doom effect!", TALKVOLUME_SHOUT); object opponent = GetLastAttacker(OBJECT_SELF); PlayAnimation( ANIMATION_LOOPING_TALK_LAUGHING ,1.0,1.0); PlaySound("sca_dragacid"); effect eVis = EffectVisualEffect( VFX_COM_CHUNK_YELLOW_SMALL); effect eArrow = EffectVisualEffect(245); DelayCommand(1.2, ApplyEffectToObject(DURATION_TYPE_INSTANT, eArrow, opponent)); DelayCommand(1.6, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, opponent)); //Declare major variables including Area of Effect Object effect eAOE = EffectAreaOfEffect(AOE_PER_CREEPING_DOOM); location lTarget = GetLocation(opponent); int nDuration = 15; //Create an instance of the AOE Object using the Apply Effect function DelayCommand(2.0,ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eAOE, lTarget, RoundsToSeconds(nDuration))); }

    and then this one as onspawn_attacked
    //::////////////////////////////////////////////////// //:: NW_C2_DEFAULT9 /* * Default OnSpawn handler with XP1 revisions. * This corresponds to and produces the same results * as the default OnSpawn handler in the OC. * * This can be used to customize creature behavior in three main ways: * * - Uncomment the existing lines of code to activate certain * common desired behaviors from the moment when the creature * spawns in. * * - Uncomment the user-defined event signals to cause the * creature to fire events that you can then handle with * a custom OnUserDefined event handler script. * * - Add new code _at the end_ to alter the initial * behavior in a more customized way. */ //::////////////////////////////////////////////////// //:: Copyright (c) 2002 Floodgate Entertainment //:: Created By: Naomi Novik //:: Created On: 12/11/2002 //::////////////////////////////////////////////////// //:: Updated 2003-08-20 Georg Zoeller: Added check for variables to active spawn in conditions without changing the spawnscript #include "x0_i0_anims" // #include "x0_i0_walkway" - in x0_i0_anims #include "x0_i0_treasure" #include "x2_inc_switches" void main() { // ***** Spawn-In Conditions ***** // // * REMOVE COMMENTS (// ) before the "Set..." functions to activate // * them. Do NOT touch lines commented out with // *, those are // * real comments for information. // * This causes the creature to say a one-line greeting in their // * conversation file upon perceiving the player. Put [NW_D2_GenCheck] // * in the "Text Seen When" field of the greeting in the conversation // * file. Don't attach any player responses. // * // SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION); // * Same as above, but for hostile creatures to make them say // * a line before attacking. // * // SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION); // * This NPC will attack when its allies call for help // * // SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET); // * If the NPC has the Hide skill they will go into stealth mode // * while doing WalkWayPoints(). // * // SetSpawnInCondition(NW_FLAG_STEALTH); //-------------------------------------------------------------------------- // Enable stealth mode by setting a variable on the creature // Great for ambushes // See x2_inc_switches for more information about this //-------------------------------------------------------------------------- if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_STEALTH) == TRUE) { SetSpawnInCondition(NW_FLAG_STEALTH); } // * Same, but for Search mode // * // SetSpawnInCondition(NW_FLAG_SEARCH); //-------------------------------------------------------------------------- // Make creature enter search mode after spawning by setting a variable // Great for guards, etc // See x2_inc_switches for more information about this //-------------------------------------------------------------------------- if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_SEARCH) == TRUE) { SetSpawnInCondition(NW_FLAG_SEARCH); } // * This will set the NPC to give a warning to non-enemies // * before attacking. // * NN -- no clue what this really does yet // * // SetSpawnInCondition(NW_FLAG_SET_WARNINGS); // * Separate the NPC's waypoints into day & night. // * See comment on WalkWayPoints() for use. // * // SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING); // * If this is set, the NPC will appear using the "EffectAppear" // * animation instead of fading in, *IF* SetListeningPatterns() // * is called below. // * //SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION); // * This will cause an NPC to use common animations it possesses, // * and use social ones to any other nearby friendly NPCs. // * // SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS); //-------------------------------------------------------------------------- // Enable immobile ambient animations by setting a variable // See x2_inc_switches for more information about this //-------------------------------------------------------------------------- if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_AMBIENT_IMMOBILE) == TRUE) { SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS); } // * Same as above, except NPC will wander randomly around the // * area. // * // SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS); //-------------------------------------------------------------------------- // Enable mobile ambient animations by setting a variable // See x2_inc_switches for more information about this //-------------------------------------------------------------------------- if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_AMBIENT) == TRUE) { SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS); } // **** Animation Conditions **** // // * These are extra conditions you can put on creatures with ambient // * animations. // * Civilized creatures interact with placeables in // * their area that have the tag "NW_INTERACTIVE" // * and "talk" to each other. // * // * Humanoid races are civilized by default, so only // * set this flag for monster races that you want to // * behave the same way. // SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED); // * If this flag is set, this creature will constantly // * be acting. Otherwise, creatures will only start // * performing their ambient animations when they // * first perceive a player, and they will stop when // * the player moves away. // SetAnimationCondition(NW_ANIM_FLAG_CONSTANT); // * Civilized creatures with this flag set will // * randomly use a few voicechats. It's a good // * idea to avoid putting this on multiple // * creatures using the same voiceset. // SetAnimationCondition(NW_ANIM_FLAG_CHATTER); // * Creatures with _immobile_ ambient animations // * can have this flag set to make them mobile in a // * close range. They will never leave their immediate // * area, but will move around in it, frequently // * returning to their starting point. // * // * Note that creatures spawned inside interior areas // * that contain a waypoint with one of the tags // * "NW_HOME", "NW_TAVERN", "NW_SHOP" will automatically // * have this condition set. // SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE); // **** Special Combat Tactics *****// // * These are special flags that can be set on creatures to // * make them follow certain specialized combat tactics. // * NOTE: ONLY ONE OF THESE SHOULD BE SET ON A SINGLE CREATURE. // * Ranged attacker // * Will attempt to stay at ranged distance from their // * target. // SetCombatCondition(X0_COMBAT_FLAG_RANGED); // * Defensive attacker // * Will use defensive combat feats and parry // SetCombatCondition(X0_COMBAT_FLAG_DEFENSIVE); // * Ambusher // * Will go stealthy/invisible and attack, then // * run away and try to go stealthy again before // * attacking anew. // SetCombatCondition(X0_COMBAT_FLAG_AMBUSHER); // * Cowardly // * Cowardly creatures will attempt to flee // * attackers. // SetCombatCondition(X0_COMBAT_FLAG_COWARDLY); // **** Escape Commands ***** // // * NOTE: ONLY ONE OF THE FOLLOWING SHOULD EVER BE SET AT ONE TIME. // * NOTE2: Not clear that these actually work. -- NN // * Flee to a way point and return a short time later. // * // SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // * Flee to a way point and do not return. // * // SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // * Teleport to safety and do not return. // * // SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // * Teleport to safety and return a short time later. // * // SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // ***** CUSTOM USER DEFINED EVENTS ***** / /* If you uncomment any of these conditions, the creature will fire a specific user-defined event number on each event. That will then allow you to write custom code in the "OnUserDefinedEvent" handler script to go on top of the default NPC behaviors for that event. Example: I want to add some custom behavior to my NPC when they are damaged. I uncomment the "NW_FLAG_DAMAGED_EVENT", then create a new user-defined script that has something like this in it: if (GetUserDefinedEventNumber() == 1006) { // Custom code for my NPC to execute when it's damaged } These user-defined events are in the range 1001-1007. */ // * Fire User Defined Event 1001 in the OnHeartbeat // * // SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); // * Fire User Defined Event 1002 // * // SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); // * Fire User Defined Event 1005 // * SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); // * Fire User Defined Event 1006 // * // SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); // * Fire User Defined Event 1008 // * // SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); // * Fire User Defined Event 1003 // * // SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); // * Fire User Defined Event 1004 // * // SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); // ***** DEFAULT GENERIC BEHAVIOR (DO NOT TOUCH) ***** // // * Goes through and sets up which shouts the NPC will listen to. // * SetListeningPatterns(); // * Walk among a set of waypoints. // * 1. Find waypoints with the tag "WP_" + NPC TAG + "_##" and walk // * among them in order. // * 2. If the tag of the Way Point is "POST_" + NPC TAG, stay there // * and return to it after combat. // // * Optional Parameters: // * void WalkWayPoints(int nRun = FALSE, float fPause = 1.0) // // * If "NW_FLAG_DAY_NIGHT_POSTING" is set above, you can also // * create waypoints with the tags "WN_" + NPC Tag + "_##" // * and those will be walked at night. (The standard waypoints // * will be walked during the day.) // * The night "posting" waypoint tag is simply "NIGHT_" + NPC tag. WalkWayPoints(); //* Create a small amount of treasure on the creature if ((GetLocalInt(GetModule(), "X2_L_NOTREASURE") == FALSE) && (GetLocalInt(OBJECT_SELF, "X2_L_NOTREASURE") == FALSE) ) { CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); } // ***** ADD ANY SPECIAL ON-SPAWN CODE HERE ***** // // * If Incorporeal, apply changes if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_IS_INCORPOREAL) == TRUE) { effect eConceal = EffectConcealment(50, MISS_CHANCE_TYPE_NORMAL); eConceal = ExtraordinaryEffect(eConceal); effect eGhost = EffectCutsceneGhost(); eGhost = ExtraordinaryEffect(eGhost); ApplyEffectToObject(DURATION_TYPE_PERMANENT, eConceal, OBJECT_SELF); ApplyEffectToObject(DURATION_TYPE_PERMANENT, eGhost, OBJECT_SELF); } // * Give the create a random name. // * If you create a script named x3_name_gen in your module, you can // * set the value of the variable X3_S_RANDOM_NAME on OBJECT_SELF inside // * the script to override the creature's default name. if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_RANDOMIZE_NAME) == TRUE) { ExecuteScript("x3_name_gen",OBJECT_SELF); string sName = GetLocalString(OBJECT_SELF,"X3_S_RANDOM_NAME"); if ( sName == "" ) { sName = RandomName(); } SetName(OBJECT_SELF,sName); } }

    and then this one named puke_onattacked

    //:://///////////////////////////////////////////// //:: Default: On User Defined //:: NW_C2_DEFAULTD //:: Copyright (c) 2002 Bioware Corp. //::////////////////////////////////////////////// /* Determines the course of action to be taken on a user defined event. */ //::////////////////////////////////////////////// //:: Created By: Don Moar //:: Created On: April 28, 2002 //::////////////////////////////////////////////// void main() { string i = IntToString(GetUserDefinedEventNumber()); SpeakString(" Event #"+i+" occured!", TALKVOLUME_SHOUT); switch (GetUserDefinedEventNumber()) { case 1005: SpeakString("i was attacked Event #1005 occured!", TALKVOLUME_SHOUT); ExecuteScript("crpdoom_effect", OBJECT_SELF); break; // ... additional case statements for other user-defined // events can be added as neccessary } }

    Set your zombies OnSpawn script to onspawn_attacked and OnUser_Defined to puke_onattacked.
    I'm trying to figure out what's wrong with the playsound call - I hear nothing from it.

    Also I still need to add a use limitation check: may add a "doomuses" variable to the zombie set to whatever you want, then it will get decremented for each use and check for remaining uses. I added a part to skip pukes within a timeframe from the last puke.

    The animations, VFX, sound wav file and delays can be easily tweaked to experiment with if you want.
    Post edited by Calgacus on
  • CalgacusCalgacus Member Posts: 273
    I guess I cannot make a sound originate on a monster immediately. A "play sound at location now" function would be a useful addition for EE. As I understand it now I have to add an invisible sound source or addd the play sound to the creatures queue. Neither is ideal as I want it played immediately and a sound source may be in the wrong position or even just not present in the area the monster has wondered to.
  • QuilistanQuilistan Member Posts: 177
    Very cool Calgacus!

    Thanks for getting this going for me. Sorry I did not reply sooner. I started work after a vacation this week and got slammed. I should get a chance to play with it this weekend a bit. I will be hoping to try different animations to get it to look right.


    the bugs are black so I might try to see if a black or dark colored breath or ray effect exists. The visual I have in my head is to mimic the scene in the movie "The Mummy" when he lets the flies out of his mouth.

    I love the "laugh" animation you put in to give them an action that looks like they are heaving.
Sign In or Register to comment.