News:

Be sure to check out the updated artwork by Vix, located in the "Art Reviews and Previews" board!

Main Menu

Charm Person

Started by Andy123, September 22, 2023, 10:41:34 PM

Previous topic - Next topic

Andy123

Looks like this spell has a bit of history with giving people grief.

https://forums.goldbox.games/index.php?topic=4034.msg58661#msg58661

I also found this, implemented the suggested changes and the spell worked:
https://github.com/grannypron/uaf_levels/commit/a949d5224412a3ef815917622b22de8eb8036d53

...except it only worked on an old version of the database which had a simpler version of the IsCharmed SA CharDisplayStatus hook:
$SET_HOOK_PARAM( 7,"Charmed ");
$SET_HOOK_PARAM( 6,"");
$RETURN 1;


The lastest version of IsCharmed:
[CharDisplayStatus] = $VAR exp; // time effect expires, gotten from SA that called this one
-exp = $SA_PARAM_GET();
-$IF ($GET_PARTY_TIME() >=# exp)
- {
- $SetFriendly($IndexOf($TargetContext()),$GET_COMBATANT_SA($TargetContext(),"side"));
- $SA_REMOVE();
- $RETURN;
- };
-$SET_HOOK_PARAM( 7,"Charmed "); $SET_HOOK_PARAM( 6,""); $RETURN 1;

...gives these errors:
You cannot view this attachment.

I'm pretty green when it comes to making sense of this stuff, but it looks to me like the latest one is calling on information about when the spell should expire which is not provided. Not sure what the issue with the non-existent actor/no target context is about, or how to fix it.

Assuming we can fix all that, I was hoping there would be a way to have the effects of the spell end after combat.




manikus

The expiration is 'exp' (which is a spell parameter passed to the script).
If you substitute "CharacterContext" for "TargetContext" the messages will go away.

Andy123

Quote from: manikus on September 23, 2023, 07:00:46 PMThe expiration is 'exp' (which is a spell parameter passed to the script).
Does that mean I should find "exp" in the SA which called on IsCharmed (in this case spell_CharmPerson) ?


Quote from: manikus on September 23, 2023, 07:00:46 PMIf you substitute "CharacterContext" for "TargetContext" the messages will go away.
TargetContext appears twice in that script. Should I switch it for CharacterContext in both places or just one of them?

manikus

Quote from: Andy123 on September 23, 2023, 09:11:43 PM
Quote from: manikus on September 23, 2023, 07:00:46 PMThe expiration is 'exp' (which is a spell parameter passed to the script).
Does that mean I should find "exp" in the SA which called on IsCharmed (in this case spell_CharmPerson) ?
No. 'exp' is a variable in this script that stands for " $SA_PARAM_GET()". This is the value assigned to "IsCharmed" when it is created.

Quote from: Andy123 on September 23, 2023, 09:11:43 PM
Quote from: manikus on September 23, 2023, 07:00:46 PMIf you substitute "CharacterContext" for "TargetContext" the messages will go away.
TargetContext appears twice in that script. Should I switch it for CharacterContext in both places or just one of them?
Yes.

Andy123

I think I get it. Variable "exp" is pulled from the line of the script that called the SA. That would be the InvokeSpellOnTarget script of the "spell_CharmPerson" SA, this line in particular:
$SET_CHARACTER_SA($TargetContext(),"IsCharmed",lvl);
...where lvl is a variable consisting of
$GET_CHAR_Lvl(atk,cls);
...where atk is the attacker, and cls is another $SA_PARAM_GET(); this time pulling from the Charm Person spell itself, returning the class of the attacker.

Long story short, "exp" refers to the result of $GET_CHAR_Lvl(attacker, class)

...which I guess would return the level of the casting class of the attacker. So if it's cast by a level 3 magic user, the effects of the spell should go away once party_time is equal to or greater than 3.

Is that 3 rounds? 3 hours? 3 days? Whatever it's supposed to be, the spell appears to have no effect (maybe 3 milliseconds then?). When I delete all the exp stuff, the spell works as intended but is permanent.

manikus

Now we're getting somewhere. ;) It does have a value, its just not the right value.

If you replace the line:
-$SET_CHARACTER_SA($TargetContext(),"IsCharmed",lvl);
with
-$SET_CHARACTER_SA($TargetContext(),"IsCharmed",$GET_PAERTY_TIME() +# lvl);
you will get a much better result.

manikus

You also need to change "spell_CharmPersonOrMammal". I will update the databases with it (and spell_CharmPerson), but for now, I've included it below.

\(BEGIN)
name = spell_CharmPersonOrMammal
[InvokeSpellOnTarget] = $VAR atk; // attacker
-$VAR tgt; // target
-$VAR tNom; // target name
-$VAR cls;
-$VAR int;
-$VAR lvl;
-$VAR exp;
-tgt = $IndexOf($TargetContext());
-atk = $IndexOf($AttackerContext());
-tNom = $GET_CHAR_NAME(tgt);
-$IF ($GET_CHARACTER_SA($TargetContext(),"saved" )) {$RETURN;};
-$IF ($GET_CANBEHELDORCHARMED($TargetContext()) != 1){$RETURN;};
-$IF ($GET_COMBATANT_SA($TargetContext(),"monster_ImmuneCharm") != "-?-?-"){$RETURN;};
-$IF ($GET_MONSTERTYPE_SA(tNom,"monsterLevel") != "-?-?-")
- {  //  MONSTERTYPE_SA checks go here
- $IF ($GET_MONSTERTYPE_SA(tNom,"IsPerson") == "-?-?-" && $GET_ISMAMMAL($TargetContext()) != 1){$RETURN;};
- };
-cls = $SA_PARAM_GET();
-int = $GET_CHAR_LIMITED_INT(tgt);
-lvl = $GET_CHAR_Lvl(atk,cls);
-$IF (int >=# 19) {exp = $GET_PARTY_TIME() +# 14400;};
-$IF (int ==# 18) {exp = $GET_PARTY_TIME() +# (14400 *# 2);};
-$IF (int ==# 17) {exp = $GET_PARTY_TIME() +# (14400 *# 3);};
-$IF (int >=# 15) {exp = $GET_PARTY_TIME() +# (14400 *# 7);};
-$IF (int >=# 13) {exp = $GET_PARTY_TIME() +# (14400 *# 14);};
-$IF (int >=# 10) { exp = $GET_PARTY_TIME() +# (14400 *# 21);};
-$IF (int >=# 7) {exp = $GET_PARTY_TIME() +# (14400 *# 30);};
-$IF (int >=# 4) {exp = $GET_PARTY_TIME() +# (14400 *# 60);};
-$IF (int <=# 3) {exp = $GET_PARTY_TIME() +# (14400 *# 90);};
-$SetFriendly(tgt,$GET_COMBATANT_SA($Myself(),"side"));
-$SET_CHARACTER_SA($TargetContext(),"IsCharmed",exp);
-$SET_CHARACTER_SA($TargetContext(),"DispelLevel",lvl);
\(END)

manikus

You also need to update "spell_CharmPlant" from:
-$SET_CHARACTER_SA($TargetContext(),"IsCharmed",lvl);
with
-$SET_CHARACTER_SA($TargetContext(),"IsCharmed",lvl +# 999999999);

Andy123

#8
Quote from: Andy123 on September 25, 2023, 06:59:59 AMWhen I delete all the exp stuff, the spell works as intended but is permanent.
Prior to you posting your answer above, I tried this in the IsCharmed SA, [CharDisplayStatus] script:
$IF ($GET_PARTY_DAYS() ># 1)
    {
        $SetFriendly($IndexOf($CharacterContext()),$GET_COMBATANT_SA($CharacterContext(),"side"));
        $SA_REMOVE();
        $RETURN;
    };
$SET_HOOK_PARAM( 7,"Charmed "); $SET_HOOK_PARAM( 6,""); $RETURN 1;

...which removes the effect after a day (I have no idea how $Get_Party_Time() is supposed to work, what unit of time it deals with etc).
Doing this, everything pretty much worked as expected.

I then saw your posts and tried making the changes you've suggested. It could just be mad coincidence, but the following happened:
  • When PCs cast Charm Person the spell works, but wears off during combat - much sooner than expected.
  • When monsters use the spellcaster item for Charm Person
    • It has no effect on PCs despite the notification "*PC* is Charmed"
    • Monsters keep casting it at the same PC, even after
      • PC is already (apparently) charmed
      • PC is downed
      • PC is downed with another PC standing on them

...which makes no sense. I appreciate my knowledge of how this all works is sketchy at best, but from what I can tell the change you've suggested should only affect the duration of the spell.

edit: continually casting at downed PCs happens with other spells as well. Seems to be a spellcaster item issue in general and probably deserves its own thread.

manikus

$GET_PARTY_TIME() returns the smallest unit, which is a second.
The Charm Person spell is not meant to last a long time, unlike some of the other charm spells which can last months under the right conditions.

Everything else you just posted needs to be in a mini-mod for hotmustard. Its an engine bug.