//////////////////////////////////////////////////////////////////////////////// // hos1_ex_night - Handle Change to Night routines // By Deva B. Winblood. April 12th, 2009 //////////////////////////////////////////////////////////////////////////////// #include "lib_hos2_shpath" int fnNotBusy(object oTarget,object oSkull) { // PURPOSE: Return TRUE if not busy object oEnemy=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oTarget,1,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY); if (GetIsInCombat(oTarget)&&GetDistanceBetween(oTarget,oSkull)<40.0) return FALSE; else if (IsInConversation(oTarget)) return FALSE; else if (GetIsDMPossessed(oTarget)) return FALSE; else if (GetIsObjectValid(oEnemy)&&GetDistanceBetween(oEnemy,oSkull)<40.0) return FALSE; return TRUE; } // fnNotBusy() void fnMakeSound(object oGhost) { // PURPOSE: Make a sound string sResRef=GetResRef(oGhost); string sSound="as_pl_crptvoice1"; if (sResRef=="ghost_female") sSound="as_pl_crptvoice4"; AssignCommand(oGhost,PlaySound(sSound)); } // fnMakeSound() void fnCheckForControllingPC(object oGhost) { // PURPOSE: See if there is a nearby controlling PC object oPC; object oMaster=GetLocalObject(oGhost,"oMaster"); object oOb; object oSkull=GetLocalObject(oGhost,"oSkull"); if (GetIsObjectValid(GetItemPossessor(oSkull))) oSkull=GetItemPossessor(oSkull); int nN; if (GetIsDay()||!GetIsObjectValid(oSkull)) { // despawn effect eDespawn=EffectVisualEffect(VFX_IMP_UNSUMMON); ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eDespawn,GetLocation(oGhost)); DelayCommand(0.5,DestroyObject(oGhost)); } // despawn else if (GetIsObjectValid(oMaster)&&GetLocalInt(oMaster,"bControlUndead")) { // master has control if (!fnNotBusy(oGhost,oSkull)) { DelayCommand(4.0,fnCheckForControllingPC(oGhost)); return; } SetAILevel(oGhost,AI_LEVEL_NORMAL); if (GetArea(oSkull)!=GetArea(oGhost)) { // must be in area of skull AssignCommand(oGhost,ClearAllActions(TRUE)); AssignCommand(oGhost,JumpToObject(oSkull)); if (d2()==1) fnMakeSound(oGhost); } // must be in area of skull else if (GetArea(oGhost)==GetArea(oSkull)) { // same area if (GetArea(oMaster)==GetArea(oGhost)&&GetDistanceBetween(oGhost,oSkull)<40.0) { // ghost can move still AssignCommand(oGhost,ClearAllActions()); if (d6()==1) fnMakeSound(oGhost); MoveToLocation(oGhost,GetLocation(oMaster),TRUE,3.0); } // ghost can move still else { // ghost too far from skull AssignCommand(oGhost,ClearAllActions()); if (d4()==1) fnMakeSound(oGhost); AssignCommand(oGhost,ActionMoveToObject(oSkull,TRUE,35.0)); } // ghost too far from skull } // same area } // master has control else if (GetIsObjectValid(oMaster)) { // master has lost control DeleteLocalObject(oGhost,"oMaster"); SendMessageToPC(oMaster,"You are no longer controlling "+GetName(oGhost)+"."); ChangeToStandardFaction(oGhost,STANDARD_FACTION_HOSTILE); AssignCommand(oGhost,ClearAllActions(TRUE)); fnMakeSound(oGhost); oOb=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oGhost,1,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY); if (GetIsObjectValid(oOb)) { // attack this target instead AssignCommand(oGhost,ActionAttack(oOb)); } // attack this target instead else if (GetIsObjectValid(oSkull)) { // seek out your skull if (GetArea(oSkull)!=GetArea(oGhost)) { // Jump AssignCommand(oGhost,JumpToObject(oSkull)); } // Jump else if (GetDistanceBetween(oSkull,oGhost)>20.0) { // move back to skull AssignCommand(oGhost,ActionForceMoveToObject(oSkull,TRUE,1.0f,60.0f)); } // move back to skull } // seek out your skull } // master has lost control else { // no master SetAILevel(oGhost,AI_LEVEL_DEFAULT); nN=1; oMaster=OBJECT_INVALID; oOb=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oGhost,nN,CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC); while(GetIsObjectValid(oOb)&&GetDistanceBetween(oOb,oGhost)<15.01&&!GetIsObjectValid(oMaster)) { // check for controlling PC if (GetLocalInt(oOb,"bControlUndead")) oMaster=oOb; nN++; oOb=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oGhost,nN,CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC); } // check for controlling PC if (GetIsObjectValid(oMaster)) { // control undead kicks in effect eVFX=EffectVisualEffect(VFX_IMP_DOMINATE_S); ApplyEffectToObject(DURATION_TYPE_INSTANT,eVFX,oGhost); SetLocalObject(oGhost,"oMaster",oMaster); string sID=GetLocalString(oMaster,"sTeamID"); object oProxy=GetObjectByTag(sID+"_PROXY"); AssignCommand(oGhost,ClearAllActions(TRUE)); ChangeFaction(oGhost,oProxy); MoveToLocation(oGhost,GetLocation(oMaster),TRUE,3.0); SendMessageToPC(oMaster,"Control undead seizes control of "+GetName(oGhost)+"."); } // control undead kicks in else { // free roaming undead if (!fnNotBusy(oGhost,oSkull)) { DelayCommand(4.0,fnCheckForControllingPC(oGhost)); return; } if (GetArea(oGhost)!=GetArea(oSkull)||GetDistanceBetween(oGhost,oSkull)>20.0) { // move to skull AssignCommand(oGhost,ClearAllActions(TRUE)); if (d4()==1) fnMakeSound(oGhost); AssignCommand(oGhost,ActionForceMoveToObject(oSkull,FALSE,1.0)); } // move to skull else { // random move location lLoc=MoveGetRandomLocation(GetLocation(oSkull),10); AssignCommand(oGhost,ClearAllActions()); if (d4()==1) fnMakeSound(oGhost); AssignCommand(oGhost,ActionMoveToLocation(lLoc,FALSE)); } // random move } // free roaming undead } // no master DelayCommand(8.0,fnCheckForControllingPC(oGhost)); } // fnCheckForControllingPC() void main() { object oMod=GetModule(); // check for skulls that have a ghost object oSkull; object oGhost; int nN=0; object oOb; string sRes; location lLoc; //SendMessageToPC(GetFirstPC(),"hos1_ex_night(): Start"); oSkull=GetObjectByTag("it_skull",nN); while(GetIsObjectValid(oSkull)) { // check all skulls //SendMessageToPC(GetFirstPC()," Skull #:"+IntToString(nN)+" found."); sRes=GetLocalString(oSkull,"sRes"); if (GetStringLength(sRes)<1) sRes="ghost_male"; oGhost=GetLocalObject(oSkull,"oGhost"); if (!GetIsObjectValid(oGhost)) { // need to spawn the ghost oOb=GetItemPossessor(oSkull); if (!GetIsObjectValid(oOb)) { // not in inventory lLoc=GetLocation(oSkull); } // not in inventory else { // in inventory lLoc=GetLocation(oOb); } // in inventory oGhost=CreateObject(OBJECT_TYPE_CREATURE,sRes,lLoc); sRes=GetLocalString(oSkull,"sName"); if (GetStringLength(sRes)>0) SetName(oGhost,sRes+"'s Ghost"); SetLocalObject(oSkull,"oGhost",oGhost); SetLocalObject(oGhost,"oSkull",oSkull); effect eVFX=EffectVisualEffect(VFX_DUR_GHOST_SMOKE); effect eSummon=EffectVisualEffect(VFX_IMP_RAISE_DEAD); DelayCommand(0.1,ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eSummon,GetLocation(oGhost))); ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVFX,oGhost); ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectCutsceneGhost(),oGhost); DelayCommand(0.3,AssignCommand(oGhost,fnCheckForControllingPC(oGhost))); } // need to spawn the ghost nN++; oSkull=GetObjectByTag("it_skull",nN); } // check all skulls //SendMessageToPC(GetFirstPC(),"hos1_ex_night(): End"); }