PGCC_PRC8/_module/nss/pda_bobo001.nss
Jaysyn904 e51634d39b Initial upload
Initial upload.
2024-10-09 14:17:22 -04:00

207 lines
8.6 KiB
Plaintext

//::///////////////////////////////////////////////
//:: Combat Dummy
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
usage:
assign this script to the OnDamaged event of a placeable
make placeable non-static & usable
assign 10.000 hp to the placeable
set hardness and all saves to 0
*/
//:://////////////////////////////////////////////
//:: Created By: Knat
//:: Modified by styzygy
//:://////////////////////////////////////////////
// -------------------------------------------------------------------
// --------------- COMBAT DUMMY START --------------------------------
// -------------------------------------------------------------------
/*
combat dummy
does not need a creature object to simulate and track combat status.
player needs to deplete a set amount of HP, depending on their level, to complete
a training session.
rewards XP one time during a specific timespan (default 1 hour realtime) ONLY
if they complete a training session. (no xp if they abort/cancel a session)
players will be able to re-train asap, but will not get any XP until said timer runs out.
it's not possible to "farm" xp, it's just a small spice up...
you can change those values easily.
combat dummy records some basic statistics like number of hits and total damage
done. It displays them during combat and a final statistic after the session is complete.
adds FX based on player damage
accounts for multiplayer.. only one active training session per dummy. other PCs attacking the
same dummy get ignored (in theory at least, never tested so far)
*/
int PLC_DUMMY_HP_MODIFIER = 10; // dummy-hp = modifier + (pc-level * modifier)
float PLC_DUMMY_XP_MODIFIER = 0.0; // adjust this to control XP output (xp = dummy-hp * modifier)
//float PLC_DUMMY_XP_TIMER = 3600.0; // XP timer in seconds. Player won't get XP again until this timer runs out
void DummyRespawn(string sResRef, location lLoc)
{
CreateObject(OBJECT_TYPE_PLACEABLE, sResRef, lLoc);
}
void DummyCheckSession(object oDummy = OBJECT_SELF)
{
object oUser = GetLocalObject(oDummy,"PLC_INTERACT_USER");
if(GetIsObjectValid(oUser))
{
if(GetIsInCombat(oUser)) // still in combat, restart timer
DelayCommand(5.0,DummyCheckSession(oDummy));
else
{
// not in combat, abort session
FloatingTextStringOnCreature("Session Aborted...",oUser);
// delete & re-create dummy
string sResRef = GetResRef(oDummy); location lLoc = GetLocation(oDummy);
AssignCommand(GetModule(),DelayCommand(0.1,DummyRespawn(sResRef,lLoc)));;
DestroyObject(oDummy);
}
}
}
void DummyMain(object oPC, object oDummy)
{
// initial user interaction, starts training session
if( !GetLocalInt(oDummy,"PLC_INTERACT_INUSE") )
{
//DelayCommand(5.0,CombatDummyReport(oPC, oDummy));
// set target PC
SetLocalObject(oDummy,"PLC_INTERACT_USER",oPC);
// set InUse flag
SetLocalInt(oDummy,"PLC_INTERACT_INUSE",TRUE);
// set strength of dummy based on player level
SetLocalInt(oDummy,"PLC_INTERACT_SESSIONHP", (GetHitDice(oPC) * PLC_DUMMY_HP_MODIFIER ) + PLC_DUMMY_HP_MODIFIER );
// initiate "check for session abort/cancel"
// this function polls every 5 sec and checks if the player is still
// fighting with the dummy. if not, session gets aborted
// and dummy gets re-created. this deletes all variables and resets
// everything to clean state.
// this "pseudo heartbeat" only runs during PC<>dummy interaction
// and is very small
DelayCommand(5.0,DummyCheckSession(oDummy));
// FloatingTextStringOnCreature("Session Started - Dummy Strength: "+IntToString(GetLocalInt(oDummy,"PLC_INTERACT_SESSIONHP")),oPC);
// if(GetLocalInt(oPC,"PLC_INTERACT_COMBATDUMMY_NOXP"))
// FloatingTextStringOnCreature("You won't get XP this time",oPC);
}
object oUser = GetLocalObject(oDummy,"PLC_INTERACT_USER");
if(oUser == oPC)
{
int nSessionHP = GetLocalInt(oDummy,"PLC_INTERACT_SESSIONHP");
int nTotalDamage = GetMaxHitPoints() - GetCurrentHitPoints();
int nHitCount;
int nLastTotalDamage = GetLocalInt(oDummy,"PLC_INTERACT_LASTHP");
nHitCount = GetLocalInt(oDummy,"PLC_INTERACT_HITCOUNT");
// register hit
if(nTotalDamage > nLastTotalDamage)
{
SetLocalInt(oDummy,"PLC_INTERACT_LASTHP", nTotalDamage);
nHitCount++;
SetLocalInt(oDummy,"PLC_INTERACT_HITCOUNT", nHitCount);
}
// apply some effects based on damage
int nDamage = nTotalDamage - nLastTotalDamage;
if (nDamage > 24) ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectVisualEffect(75), OBJECT_SELF);
if (nDamage > 12) ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectVisualEffect(281), OBJECT_SELF);
if (nDamage > 6) ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectVisualEffect(112), OBJECT_SELF);
if (nDamage > 3) ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectVisualEffect(236 + d3()), OBJECT_SELF);
SendMessageToPC(oPC, IntToString(nTotalDamage) + " damage, " + IntToString(nHitCount) + " hits.");
if(nTotalDamage > nSessionHP) // session done - dummy HP depleted
{
if (GetLocalInt(OBJECT_SELF,"DO_ONCE") == 1) return;
SetLocalInt(OBJECT_SELF,"DO_ONCE",1);
FloatingTextStringOnCreature("You have finished your training session",oPC);
// report final statistic
int nAvgDam = nTotalDamage/nHitCount;
AssignCommand(GetModule(),DelayCommand(2.0,FloatingTextStringOnCreature("You inflicted "+IntToString(nTotalDamage)+ " damage to the dummy with "+IntToString(nHitCount)+" hits",oPC)));
AssignCommand(GetModule(),DelayCommand(4.0,FloatingTextStringOnCreature("Your average damage is " + IntToString(nAvgDam)+" per attack",oPC)));
int nIdx;
int nRank;
int nHolder=0;
int nAvgDamHolder;
string sNameHolder;
for (nIdx = 10; nIdx > 0; nIdx--)
{
nHolder = GetCampaignInt("PGC3_DATA", "BOBO_AVGDAM_"+IntToString(nIdx));
//debug SendMessageToPC(oPC, IntToString(nIdx)+"="+IntToString(nHolder));
if (nAvgDam > nHolder) nRank = nIdx;
}
//debug SendMessageToPC(oPC, "Rank="+IntToString(nRank));
if (nRank < 11)
AssignCommand(GetModule(),DelayCommand(6.0,FloatingTextStringOnCreature("Your score ranks #"+IntToString(nRank)+" on the Best Bobo Bashers list.", oPC)));
// save stats in campaign db
for (nIdx = 9; nIdx >= nRank; nIdx--)
{
nAvgDamHolder = GetCampaignInt("PGC3_DATA", "BOBO_AVGDAM_"+IntToString(nIdx));
sNameHolder = GetCampaignString("PGC3_DATA", "BOBO_NAME_"+IntToString(nIdx));
SetCampaignInt("PGC3_DATA", "BOBO_AVGDAM_"+IntToString(nIdx+1), nAvgDamHolder);
SetCampaignString("PGC3_DATA", "BOBO_NAME_"+IntToString(nIdx+1), sNameHolder);
//debug SendMessageToPC(oPC, IntToString(nIdx+1)+") Set Name="+sNameHolder+", Set AvgDam="+IntToString(nAvgDamHolder));
}
SetCampaignInt("PGC3_DATA", "BOBO_AVGDAM_"+IntToString(nRank), nAvgDam);
//SetCampaignString("PGC3_DATA", "BOBO_NAME_"+IntToString(nRank), GetName(oPC));
string sWeaponName = "bare hands";
if (GetLastWeaponUsed(oPC) != OBJECT_INVALID) sWeaponName = GetName(GetLastWeaponUsed(oPC));
SetCampaignString("PGC3_DATA", "BOBO_NAME_"+IntToString(nRank), GetName(oPC) + ", with " + sWeaponName);
// award xp only if permitted
// if(GetLocalInt(oPC,"PLC_INTERACT_COMBATDUMMY_NOXP"))
// AssignCommand(GetModule(),DelayCommand(8.0,FloatingTextStringOnCreature("No XP reward ! You trained too recently...",oPC)));
// else
// {
// // award xp and report it to the user
// AssignCommand(GetModule(),DelayCommand(8.0,FloatingTextStringOnCreature("You earned " + IntToString( FloatToInt( IntToFloat(nSessionHP) * PLC_DUMMY_XP_MODIFIER ) ) + " xp for your training",oPC)));
// AssignCommand(GetModule(),DelayCommand(9.0,GiveXPToCreature(oPC,FloatToInt( IntToFloat(nSessionHP)* PLC_DUMMY_XP_MODIFIER ) ) ) );
// set no-xp flag
// SetLocalInt(oPC,"PLC_INTERACT_COMBATDUMMY_NOXP",TRUE);
// set deletion timer for no-xp flag
// AssignCommand(GetModule(),DelayCommand(PLC_DUMMY_XP_TIMER,DeleteLocalInt(oPC,"PLC_INTERACT_COMBATDUMMY_NOXP")));
// }
// destroy & re-create dummy
string sResRef = GetResRef(oDummy); location lLoc = GetLocation(oDummy);
AssignCommand(GetModule(),DelayCommand(0.1,DummyRespawn(sResRef,lLoc)));;
DestroyObject(oDummy);
}
}
else
SendMessageToPC(oPC,"Bobo is busy now.");
}
void main()
{
object oLastDamager = GetLastDamager();
if(GetIsObjectValid(oLastDamager))
{
//SendMessageToPC(GetFirstPC(),"Last Damager: "+GetName(oLastDamager));
DummyMain(oLastDamager,OBJECT_SELF);
}
}