Skip to content

Commit

Permalink
fixed pickpocket xp, animal empathy no longer gives xp, fixed sharwyn…
Browse files Browse the repository at this point in the history
…'s quest elixir being unreachable
  • Loading branch information
b5635 committed Sep 29, 2023
1 parent 523be7b commit 2bc2bf9
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 32 deletions.
212 changes: 207 additions & 5 deletions src/git/sewers_north.git.json
Original file line number Diff line number Diff line change
Expand Up @@ -90388,15 +90388,15 @@
},
"Appearance": {
"type": "dword",
"value": 15010
"value": 194
},
"AutoRemoveKey": {
"type": "byte",
"value": 0
},
"Bearing": {
"type": "float",
"value": 1.1045
"value": 1.1048
},
"BodyBag": {
"type": "byte",
Expand Down Expand Up @@ -90540,7 +90540,7 @@
},
"PortraitId": {
"type": "word",
"value": 0
"value": 15088
},
"Ref": {
"type": "byte",
Expand Down Expand Up @@ -90655,17 +90655,219 @@
}
]
},
"VisTransformList": {
"type": "list",
"value": [
{
"__struct_id": 6,
"AnimationSpeed": {
"__struct_id": 0,
"type": "struct",
"value": {
"__struct_id": 0,
"LerpType": {
"type": "int",
"value": 0
},
"TimerType": {
"type": "int",
"value": 0
},
"ValueTo": {
"type": "float",
"value": 1.0
}
}
},
"RotateX": {
"__struct_id": 0,
"type": "struct",
"value": {
"__struct_id": 0,
"LerpType": {
"type": "int",
"value": 0
},
"TimerType": {
"type": "int",
"value": 0
},
"ValueTo": {
"type": "float",
"value": 0.0
}
}
},
"RotateY": {
"__struct_id": 0,
"type": "struct",
"value": {
"__struct_id": 0,
"LerpType": {
"type": "int",
"value": 0
},
"TimerType": {
"type": "int",
"value": 0
},
"ValueTo": {
"type": "float",
"value": 0.0
}
}
},
"RotateZ": {
"__struct_id": 0,
"type": "struct",
"value": {
"__struct_id": 0,
"LerpType": {
"type": "int",
"value": 0
},
"TimerType": {
"type": "int",
"value": 0
},
"ValueTo": {
"type": "float",
"value": 0.0
}
}
},
"ScaleX": {
"__struct_id": 0,
"type": "struct",
"value": {
"__struct_id": 0,
"LerpType": {
"type": "int",
"value": 0
},
"TimerType": {
"type": "int",
"value": 0
},
"ValueTo": {
"type": "float",
"value": 1.0
}
}
},
"ScaleY": {
"__struct_id": 0,
"type": "struct",
"value": {
"__struct_id": 0,
"LerpType": {
"type": "int",
"value": 0
},
"TimerType": {
"type": "int",
"value": 0
},
"ValueTo": {
"type": "float",
"value": 1.0
}
}
},
"ScaleZ": {
"__struct_id": 0,
"type": "struct",
"value": {
"__struct_id": 0,
"LerpType": {
"type": "int",
"value": 0
},
"TimerType": {
"type": "int",
"value": 0
},
"ValueTo": {
"type": "float",
"value": 1.0
}
}
},
"Scope": {
"type": "int",
"value": 0
},
"TranslateX": {
"__struct_id": 0,
"type": "struct",
"value": {
"__struct_id": 0,
"LerpType": {
"type": "int",
"value": 0
},
"TimerType": {
"type": "int",
"value": 0
},
"ValueTo": {
"type": "float",
"value": 0.0
}
}
},
"TranslateY": {
"__struct_id": 0,
"type": "struct",
"value": {
"__struct_id": 0,
"LerpType": {
"type": "int",
"value": 0
},
"TimerType": {
"type": "int",
"value": 0
},
"ValueTo": {
"type": "float",
"value": 0.5
}
}
},
"TranslateZ": {
"__struct_id": 0,
"type": "struct",
"value": {
"__struct_id": 0,
"LerpType": {
"type": "int",
"value": 0
},
"TimerType": {
"type": "int",
"value": 0
},
"ValueTo": {
"type": "float",
"value": 0.17
}
}
}
}
]
},
"Will": {
"type": "byte",
"value": 0
},
"X": {
"type": "float",
"value": 48.72
"value": 49.12
},
"Y": {
"type": "float",
"value": 105.4421
"value": 105.44
},
"Z": {
"type": "float",
Expand Down
1 change: 1 addition & 0 deletions src/nss/ai_onspawn.nss
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ void GeneratePickpocketItem(string sType = "")
SetDroppableFlag(oItem, FALSE);
SetPickpocketableFlag(oItem, TRUE);
SetLocalInt(OBJECT_SELF, "pickpocket_xp", 1);
SetLocalInt(oItem, "pickpocket_xp", 1);
}

//const int GS_TIMEOUT = 7200; //2 hours
Expand Down
61 changes: 60 additions & 1 deletion src/nss/on_item_acq.nss
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,50 @@ doing so, do this only if running original event has no longer sense.
#include "inc_treasure"
#include "inc_quest"
#include "nwnx_feedback"
#include "inc_party"

void GiveCreatureSkillXP(object oTarget, object oPC, string sSkill)
{
if (GetIsDead(oTarget)) return;
if (GetIsPC(oTarget)) return;

string sIdentifier = "skill_xp_"+GetName(oPC) + GetPCPublicCDKey(oPC);

// this cannot be awarded again until reset
if (GetLocalInt(oTarget, sIdentifier) == 1) return;


SetLocalInt(oTarget, sIdentifier, 1);
DelayCommand(1800.0, DeleteLocalInt(oTarget, sIdentifier)); // reset in 30 minutes

// we use party data to award XP. That means to maximize XP value, you must be solo or far away enough from people.
// Does that seem odd? Yes. But this is the way to make sure that the correct XP is accounted for if they kill the creature with a party
// (players can get more potential XP if they use a skill in a party versus killing them without any successful skill uses)
// another way to think about it, pickpocketing NPCs or using animal empathy with a party is less risky because you have a party to back you up in case shit hits the fan and they aggro

int bAmbush = FALSE;
if (GetLocalInt(oTarget, "ambush") == 1)
{
bAmbush = TRUE;
}

int bBoss = GetLocalInt(oTarget, "boss");
int bSemiBoss = GetLocalInt(oTarget, "semiboss");
int bRare = GetLocalInt(oTarget, "rare");
float fMultiplier = 1.0;
if (bBoss == 1)
{
fMultiplier = 3.0;
}
else if (bSemiBoss == 1 || bRare == 1)
{
fMultiplier = 2.0;
}

float fXP = GetPartyXPValue(oTarget, bAmbush, Party.AverageLevel, Party.TotalSize, fMultiplier) * SKILL_XP_PERCENTAGE;

GiveXPToPC(oPC, fXP, FALSE, sSkill);
}

void main()
{
Expand Down Expand Up @@ -91,6 +135,21 @@ void main()
AddKeyToPlayer(oPC, oItem);
}

// TODO: Count gold for XP
if (!GetIsPC(oOwner) && GetIsObjectValid(oOwner) && GetObjectType(oOwner) == OBJECT_TYPE_CREATURE && !GetIsDead(oOwner) && GetLocalInt(oItem, "pickpocket_xp") == 1)
{
IncrementPlayerStatistic(oPC, "pickpockets_succeeded");

if (GetLocalInt(oOwner, "pickpocket_xp") == 1)
{
GiveCreatureSkillXP(oOwner, oPC, "Pickpocketing");
}

// we no longer track pickpockets that fail, not sure if that is possible
}

DeleteLocalInt(oItem, "pickpocket_xp");

// cleaner solution is to do it on nwnx before action events, unfortunately it doesnt fire when taking items from containers, only NWNX_ON_INVENTORY_REMOVE_ITEM_BEFORE does
// which doesn't have an object for the item remover
if (GetTag(oItem) == "quest")
Expand All @@ -100,7 +159,7 @@ void main()
NWNX_Feedback_SetFeedbackMessageHidden(NWNX_FEEDBACK_ITEM_LOST, TRUE, oPC);
return;
}

// Item containers should retroactively be given unique power self only for renaming
if (nBaseItemType == BASE_ITEM_LARGEBOX)
{
Expand Down
27 changes: 3 additions & 24 deletions src/nss/on_pc_skilla.nss
Original file line number Diff line number Diff line change
Expand Up @@ -49,29 +49,7 @@ void GiveSkillXP(object oTarget, object oPC, string sSkill)

void main()
{
if (StringToInt(NWNX_Events_GetEventData("SKILL_ID")) == SKILL_PICK_POCKET)
{
AssignCommand(OBJECT_SELF, ActionPlayAnimation(ANIMATION_FIREFORGET_STEAL));
if (GetIsPC(OBJECT_SELF))
{
if (StringToInt(NWNX_Events_GetEventData("ACTION_RESULT")))
{
IncrementPlayerStatistic(OBJECT_SELF, "pickpockets_succeeded");

object oTarget = StringToObject(NWNX_Events_GetEventData("TARGET_OBJECT_ID"));
if (GetLocalInt(oTarget, "pickpocket_xp") == 1)
{
GiveSkillXP(oTarget, OBJECT_SELF, "Pickpocketing");
DeleteLocalInt(oTarget, "pickpocket_xp");
}
}
else
{
IncrementPlayerStatistic(OBJECT_SELF, "pickpockets_failed");
}
}
}
else if (StringToInt(NWNX_Events_GetEventData("SKILL_ID")) == SKILL_ANIMAL_EMPATHY)
if (StringToInt(NWNX_Events_GetEventData("SKILL_ID")) == SKILL_ANIMAL_EMPATHY)
{
object oTarget = StringToObject(NWNX_Events_GetEventData("TARGET_OBJECT_ID"));

Expand All @@ -80,10 +58,11 @@ void main()
object oMaster = GetLocalObject(oTarget, "master");

SetIsTemporaryEnemy(OBJECT_SELF, oMaster);

/*
if (GetIsPC(OBJECT_SELF) && StringToInt(NWNX_Events_GetEventData("ACTION_RESULT")))
{
GiveSkillXP(oTarget, OBJECT_SELF, "Animal Empathy");
}
*/
}
}
Loading

0 comments on commit 2bc2bf9

Please sign in to comment.