Project krypto :)

Thought I would post something to liven up your day. I present, Project krypto:


But just to make this Witcher 3 related... (the picture is about Greek cults and hidden geometric designs)... 2001: A Space Odyssey joke included for ref.

This (0x80) null pointer still exists:

Probably the most useful mod, which wasn't baked into the update:

I was actually working on the exact same thing, then work called, and someone finished it before I had the chance. ;)

Of course, it probably needs updating now that the scipts have been altered.

Still, ask your boss if he needs a philosopher. The arcana, as seen above, which I discovered, is the greatest aristocratic joke of the century. I herd Witcher series had a few jokes about aristorats, so I though I could contribute. But, you won't be able to interpret the image without help. Sure, it's informal, but I'm not a very practical person. :)
Post automatically merged:

Oh, before I forget... This is what started it all... Contains q702_regis_decal (Virobouros) asset, so I suppose it's related. :)

Not sure if this is considered 'politics', but it's not discussion, and sarcasm is protected. ;p


Post automatically merged:

What else can I say about the update? Well, quick-cast signs don't factor in alternate sign mode, so it's nearly useless. Not sure if it handles Ciri interactions either. You should have just used my quick-cast mod, which I now probably have to update. Actually, I wouldn't have discovered the 0x80 crash without it.

NPC spawns don't lag the viewport every time now, only the first few groups do. Menus are more responsive. Also, does 'next-gen' mean it now uses more than 4GB vram? Sadly, no, but it now uses 2GB 'shared' vram.

I removed the old mod a while back:

I may update it at some point... it all depends. I actually managed to solve the fist-fight issue, after resolving all the checks being in the wrong places. One of my check was also in the wrong place. I never did upload the revised version though.
Last edited:
I just confirmed the code for quick sign casting (called 'alt' or alternate casting in code) does not factor in alternate sign mode, which are not the same thing. I did not confirm Ciri and horse interactions. A lot of the code looks rather unnecessary though. The way I handled alternate sign mode was hold to cast for 0.2 secs. May need to increase that value on console due to button-mashing effect. Furthermore, your console binds should probably be trigger+dpad not trigger+(sprint, block, dodge, heavy attack, light attack)... so you can still operate the right analog for igni viewport, etc... although dpad=4, shrug.

Also, I couldn't help but notice 1 bomb and 1 pocket slot have been removed, replaced by a useless mask slot? Fine example of consolification. :)

Other changes I noticed in the code, bunch of horse changes or fixes? Calling horse now requires double-tap? Will have to fix that console 'feature' too.

Horse has a kick animation, super-charged signs (not sure what that is about), 3 bleed and 1 Reinald_Philitre effects, NGE and DLC fixes, set bonuses, photo mode, etc...

The vast majority of the changes though, are related to new Galaxy client in-game functions, rewards, menus and GUI options.

Post automatically merged:

Error located in .\bin\config\r4game\user_config_matrix\pc\input.xml <Var builder="Input" id="Interaction">

",BuryBody" should be ";BuryBody" - Not sure what this action is used for, or if commas are acceptable syntax in this case, but the rest use semicolons.

Another error: Azerty/Qwertz keyboard configs lack default bindings for Photo Mode, and possibly others.

Just got around to updating the mod now. Localization and item template fixes remaining, and modify code taking into account new changes.

Updates complete. Need to test and update it to take recent v4 changes into account. If you're loading custom menus, you must edit .\bin\config\r4game\user_config_matrix\pc\dx12filelist.txt and dx11filelist.txt to include the .xml config files, or they will fail to load. Otherwise, everything seems to still work, besides the old wcc_lite OOM error.
Post automatically merged:

Apparently, alternate mode casting does work. I forgot you need to slot the skill. However, it does not appear to be respecting the value of IK_None=(Action=CastSignHold,State=Duration,IdleTime=2), default 0.2, since it does not contain specific key bindings, there is no actual reference to which key is being held down and for how long. Is the duration hard coded?

Using private function AltCastSign(signType : ESignType) instead of event OnCastSign( action : SInputAction ), so passing a sign type instead of the actual input action...

Ah yes, before I forget. Water reflections appear busted and there's tons of texture z-fighting going on all over the place.

There is an issue with some rocks, bodies, cliffs, etc not casting shadows. This appears related to the shadow LOD field around Geralt. It's causing strange issues. It also causes trees to shimmer close to the character. When setting it to Ultra+, the effect is pushed back a bit, so less noticeable but still present. When cast on some textures, the entire field appears as a shadow, in the wrong direction, when it should not. 'Shadow popping' is now a thing.

Similiar posts describing issues with RT and non-RT shadows and lack of HBAO:

Post #43 and #44 in this thread also contain random visual glitches.

Although I may create a post at some date with screenshots, I should not have to. It's pretty obvious what is going on, including the fade to gray-dient water screenspace reflections. Many features simply appear to be busted. Screen space reflections, ambient occlusion, dynamic lighting and shadows, shadow lods, texture z-fighting, missing or corrupt textures, etc...
Last edited:
Well, this insta-cast signs code is a mess. private function AltCastSign(signType : ESignType) is basically a duplicate of event OnCastSign( action : SInputAction ), without the need to pass an input action... However, you should never use a function, and instead use the event, since other events may block the action... so you're introducing a possible race condition somewhere, besides duplicating code. All this honestly does is avoid the need for 5 'hold' keybinds for each 'select'... which is a simple task, and solves the idletime variable not being read or respected. There are several unused or empty functions and if statements as well.

Curiously though, you modified many of the same instances of code as my mod, and in many of the same ways... except for adding the 5 keybinds, which was crucial. :)
Post automatically merged:

Yea, so I just replaced your quick/insta cast sign code with mine. It's basically the same thing, and works better. Several issues have become apparent now. Alternate sign mode activating while mashing the key or double-tapping doesn't occur with my version, probably because I'm setting the action.aName to 'CastSign', instead of 'SelectYrden', etc... so it is properly handled, in combination with additional 'hold' binds to properly detect presses and hold times. The other is that all the code you created for the 5 gamepad keys, which trigger AltSignCast(), and this 'duplicate' function itself, add unnecessary complexity. You can also just create duplicate binds (multiple actions bound to the same key), then only activate them in script when the instacast flag is set to enabled. Much simpler... and adheres to current practices.

public function GetSignActionValue() : float
if( _InstaCastSigns )
switch( GetWitcherPlayer().GetEquippedSign() )
case ST_Aard : return theInput.GetActionValue( 'SelectAardHold' );
case ST_Yrden : return theInput.GetActionValue( 'SelectYrdenHold' );
case ST_Igni : return theInput.GetActionValue( 'SelectIgniHold' );
case ST_Quen : return theInput.GetActionValue( 'SelectQuenHold' );
case ST_Axii : return theInput.GetActionValue( 'SelectAxiiHold' );
return theInput.GetActionValue( 'CastSignHold' );
Post automatically merged:

And I just confirmed the quick-cast sign keys (3-7, select) do not trigger Ciri special attack or Roach Axii, which is problematic since you still need the old 'cast' key. Also, not sure if this was an issue before, but the Mutation 'Metamorphosis' applies when casting Axii on roach, for free 'crits'? Who doesn't use Metamorphosis? That thing is just broken (so is Griffin set bonus)... and now you can stack 5 random decoctions for free just by casting Axii on Roach. :D

As a side note: The mod is almost ready. Initial release will lack gamepad support and contain some debug messages, and residual code until I can sort out 1 or 2 more issues. Now, if I could only devise a method to reserve 3 thread messages, instead of them auto-merging for the mod thread. :\

Edit: I've run into a 'small' problem... I now recall what the previous issue was... and I did solve part of it, but it seems that it cannot be solved. I can try to have another stab at it, but may simply trip and fall on my own sword. The issue is really the way weapon-selection works, and specifically the loopy nature of DelayedTryToReequipWeapon(), etc... - event OnCombatStart() - event OnReactToBeingHit( damageAction : W3DamageAction ) - timer function DelayedTryToReequipWeapon( dt: float, id : int ) - public function PrepareToAttack( optional target : CActor, optional action : EBufferActionType ) - public function GoToCombatIfNeeded( optional enemy : CActor ) : bool - public function GoToCombatIfWanted( ) : bool - protected function DoAttack(animData : CPreAttackEventData, weaponId : SItemUniqueId, parried : bool, countered : bool, parriedBy : array<CActor>, attackAnimationName : name, hitTime : float) - public final function GetMostConvenientMeleeWeapon( targetToDrawAgainst : CActor, optional ignoreActionLock : bool ) : EPlayerWeapon - public function GetMostConvenientMeleeWeapon( targetToDrawAgainst : CActor, optional ignoreActionLock : bool ) : EPlayerWeapon - public function DetermineCorrectWeapon(curTarget : CActor) : EPlayerWeapon

Well, I found part of the problem... For some reason, public function ProcessCombatActionBuffer() is not respecting !IsActionAllowed(EIAB_DrawWeapon)... It simply bypasses it for some unknown reason when pressing SteelSword or SilverSword... even though it doesn't remove the blocks itself, while this statement works elsewhere, and the action is blocked... ie: OnReactToBeingHit or DoAttack. I think it's time to have a look at this IsActionAllowed() function...

Turns out this action is not blocked for the Gwent tourney quest, it's simply blocked for onhit and doattack animations, as was expected. There's nothing awkward in this function. It's simply fist fight logic gone Dwarven...

Well, that's odd... v4.0 no longer prevents you from using swords in that sequence, but it does prevent signs, and the dwarves are set to unconscious instead of death, both suggesting it should be a fist fight. Something changed in the code since v1.32 or earlier. Wish I could just check if an NPC was set to unconscious. Unfortunately, it's not that simple, as that feature may be used by story quests as well, which actually require weapons and not fists.

I suppose if CDPR doesn't want to block EIAB_DrawWeapon during the Turn, Turn, Tournament quest then it's not my problem. The rest seems to work fine. Started a new game to give it a spin, and the first fist fight works fine, weapon swapping now works correctly. However, the tutorial still expects you to open quick access and use the quick access key to throw a bomb, or the tutorial gets stuck. You should implement my quick bomb, pocket and crossbow (Q, Z, C) keys as well, if you're gonna implement quick cast signs, and fix the tutorial. I don't ever want to see a radial menu again. :D

Well, I was going to add a simple 'track next quest' function to the mapMenu, but then I realized, or rather forgot, that keybinds and button icons are stored in the .redswf file, which I can't decompress, and takes forever to edit... Otherwise, it's a trivial matter, except that I can't add a keybind without editing the swf file hehe... why didn't you add a flash function to create buttons and binds from script? I will never understand... you still have to define them in script.:D
Last edited:
Everything seems so simple, before it becomes a problem...
game\gui\menus\!CR4JournalQuestMenu::OnTrackQuest(tag=None) Line 343
[Frames below contains callstack from native code]
<Unknown File> (0)!AK::Monitor::PostString
Can't even to do this:
Because it doesn't completely update the UI, because it's in flash, bound to mouse and keyboard events. :D
It's so weird. It will update tracked marker and objectives, but not title and description...
function UpdateDescription( entryName : name )
Calling this function appears to do nothing. It isn't even referenced in code. It triggers a breakpoint though. Flash functions are probably broken. And I just confirmed a bug... when selecting 'Locals' (members) in scriptstudio on a breakpoint, it crashes... Even having the Locals tab open and in view when the breakpoint halts execution is enough to crash it.

I can see it's reading the description of the quest though, but it's not updating the flash variable correctly, probably because there's some overriding code in the flash which sets the description and title based on some other factor, like what is currently selected. I've tried changing the selection (CR4ListBaseMenu), but it just won't update...

Well, the scriptstudio breakpoint crash is due to the option 'show unfiltered properties in locals window'. I remember solving that previously somehow... as for the flash functions? I just can't any more... I've literally had it... I've verified currentTag, lastSentTag, lastSelectedQuestTag, InitialTrackedQuest, etc... are all correct... I've even modified uiSavedData... I've tried to refresh the menu state, save state data... Literally nothing works. You can select a new option (OnEntrySelected), but you can't deselect the old, which is confirmed by pressing space activating the old objective in the UI. You cannot update description and title. All the data is there, and correct in local data structure, but the flash is not reflecting those changes - only some of them, selectively.

There's even a bug in the flash code which does not remove the selection box when moving down from the current selection to a new section.

I won't even mention the file called - woops...

All of this while making pierogi and pierniki... because 'pi' is a cult thing... :D
Last edited:
You may as well move this to the modding forum... since that's what it's become... I have 2 issues for you, both of which I've already solved. Just notifying you of these problems, but they're technically years old, some of it modified in v4.00.
if( disableAutoSheathe )
ret = PW_Fists;
This is awkward in some situations. In general, issues exist in auto-swapping from fists.
if ( weaponType == PW_Steel || weaponType == PW_Silver )
this.OnEquipMeleeWeapon( weaponType, false );
This is also causing issues in swapping from fists, in OnCombatStart, if you hit attack just before combat starts.
if ( weaponType != PW_Fists && weaponType != PW_None && weaponType != this.GetCurrentMeleeWeaponType() )
OnEquipMeleeWeapon( weaponType, false );
Or this in OnReactToBeingHit.
if ( targetToDrawAgainst.IsHuman() && ( !hasPhysicalWeapon || ( targetToDrawAgainst.GetAttitude( thePlayer ) != AIA_Hostile ) ) )
ret = PW_Fists;
There's also this, which is causing Geralt to switch to fists when an archer swaps weapons. Although, technically it is checking their inventory, it is somehow failing this condition. Maybe the melee weapon is not yet equipped and the bow (in inventory) doesn't count as a 'physical' weapon? When the bow is equpped it works differently and only checks if they're hostile and use vitality. Not sure, haven't looked at it in detail.

I've already fixed most of it btw. On top of what's in the previous mod thread, I also added random bolt and petard selection when ammo reaches zero, along the lines of random food and alcohol consumption. Improved menu screen responsiveness, but still need to remove the background during transitions. Need to fix the crossbow boat bug, horses work fine. Added a 'god mode' for player and all characters, in case you need to test weapon onhit effects, etc...

edit: Now added Auto Apply Oils, but I'm getting carried away here, so I need to test all this stuff and add a few extra checks, clean up the code, etc... The two things I need a radial menu for are potions and decoctions, but that's not going to happen any time soon... edit: Yea, it all works, no prob... needs house keeping, I'll fix the boat crossbow issue later.

One thing I wish actually worked is the witcherLog... it only displays 2 lines for 0.5 secs each. Sometimes it fails to display anything at all... Cannot alter the number of lines, or display duration, as script would suggest. Config says 3 lines, but 1 is invisible, var doesn't work, Flash thing... Also wish it could display small icons for items such as as alch/crafting/loot/food.

Managed to squash a few other bugs, here's one, simple enough. The item is not yet selected.
else if( ( slot == EES_Petard1 || slot == EES_Petard2 ) && inv.IsItemBomb( item ) )
/* else if( ( slot == EES_Petard1 || slot == EES_Petard2 ) && inv.IsItemBomb( GetSelectedItemId() ) ) */
SelectQuickslotItem( slot );
Well, I just tested fisty-cuffs and that still works. Not sure what else is left to test. Will wait till next patch drops before uploading though.
event OnEquipBolt( boltItemId : SItemUniqueId )
if( inv.IsIdValid(boltItemId) && inv.GetItemCategory(boltItemId) == 'petard')
if(thePlayer.IsActionAllowed( EIAB_OpenInventory ))
case 'q703_paint_bomb_red':
I have no words to describe this. It's like the Oil Monster Category functions... but why? petards are bolts now? :D

Currently, the only way to distinguish them and Snowballs from normal petards is the tag NoAdditionalAmmo?

Nope, snowballs have the exact same cat and tags as standard petards, so have to use the item name or ability name? :D

Nevermind, I'm adding my own tags... It's the same thing with Oils, which are a disaster... 'level' is not defined for food, etc...

You could just add Quest <tags> to paint bombs and snowballs or PetardSpecial <tags> or whatever to classify them all.

Feromone bombs are another strange exception. It's a petard without Petard <tags>. Should also be considered a PetardSpecial.

Instead of extending the data structure to include EMonsterCategory... you have 5 dozen useless functions and properties...
etc... data structure should include a property for array<EMonsterCategory> instead... so much simpler than this...

I just hacked it into Tags for now... <tags> MC_Necrophage... 'good enough'... :D

And then, you know, you have something similar in the Bestiary... except it's not in the data structure either...

Or add EMonsterCategory to the ability, so you can attach multiple abilties in an array, each with their own attack, resist, other effects, etc... instead of array<EMonsterType> with shared effects for all creatures in the array.

Or is it that... you want 1 ability to be able to affect all monster types simultaneously, with different attack and resist for each? It's possible... but then, you could just attach an array to each ability instead of all these extra properties.
<ability name="NecrophageOil_3">
<ModifyDamage type="add" min="1.1" max="1.1" />
<ModifyDefense type="add" min="0.2" max="0.2" />
<StaggerEffect is_ability="true" />
<level type="add" min="3" />
Similar to what you have for petards, and can actually be extended to petards. For more creature types use NecrophageOil_3A, 3B, etc... or ie: HangedManVenom_Human_3, HangedManVenom_Animal_3... or just Oil_Human_3, Oil_Animal_3, Oil_Necrophage_3...

Although, technically, it ought to be <ability name="Oil_Necrophage"> then <level name="3"> then effects listed under that:
<ability name="Oil_Necrophage">
<StaggerEffect is_ability="true" />
<level name="1" />
<level name="2" />
<level name="3">
<ModifyDamage type="add" min="1.1" max="1.1" />
<ModifyDefense type="add" min="0.2" max="0.2" />
I suppose it's a bit less memory efficient to store all levels in the ability, so you may want to just keep levels separate.

Furthermore, there is some oversight in application of oils. When the oil effect already exists, it is reapplied, not removed. However, this circumvents GetSelfInteraction for EET_Oil, unless it is a new oil being applied. This simply means you don't have a chance to set EEffectInteraction, and the oil is always 'cumulated' in that sense if it is already applied, and cannot be denied, since AddEffectCustom( buffParams ) is never called. However, if level 2 is applied, and the player has 'S_Alchemy_s06' (whatever that mutation is), then level 3 will be applied on top of the level 2. Not sure if this is cumulative in the sense that damage can stack from both. It's not an issue as is, since you can't have 2 separate levels of oil, except just after crafting one, but is an obstacle in certain cases. I suppose this can easily be fixed by commenting out the 'existingOil' checks. I'll try that.

edit: Well, not so easy, but managed to fix that too. Oils now correctly pass through the effect interactions processor. Required a reformulation of the ApplyOil() function and some work on but it works... Oils are now removed after it is applied, and ReApply(maxCount) now occurs in CumulateWith() as it should. This is why EEffectInteract exists... but lacks an EI_Cancel to prevent cycling the array for old vs new twice... :D

I need someone to check my code. I removed half the function. ;o
public function ApplyOil( oilId : SItemUniqueId, usedOnItem : SItemUniqueId ) : bool
var oilAbilities : array<name>;
var ammo, ammoBonus : float;
var dm : CDefinitionsManagerAccessor;
var buffParams : SCustomEffectParams;
var oilParams : W3OilBuffParams;
var oilName : name;
var min, max : SAbilityAttributeValue;
var i, A6level : int;
var oils : array<W3Effect_Oil>;
var interactResult : EEffectInteract;

if( !CanApplyOilOnItem(oilId, usedOnItem) ) return false;

dm = theGame.GetDefinitionsManager();
inv.GetItemAbilitiesWithTag(oilId, theGame.params.OIL_ABILITY_TAG, oilAbilities);
oilName = inv.GetItemName(oilId);
oils = inv.GetOilsAppliedOnItem(usedOnItem);

if ( CanUseSkill(S_Alchemy_s06) ) CheckForPreviousLevelOilExploit(oilName,oils);

ammo = CalculateAttributeValue(inv.GetItemAttributeValue(oilId, 'ammo'));
if ( CanUseSkill(S_Alchemy_s06) )
ammoBonus = CalculateAttributeValue(GetSkillAttributeValue(S_Alchemy_s06, 'ammo_bonus', false, false));
ammo *= 1 + ammoBonus * GetSkillLevel(S_Alchemy_s06);

buffParams.effectType = EET_Oil;
buffParams.creator = this;
oilParams = new W3OilBuffParams in this;
oilParams.iconPath = dm.GetItemIconPath(oilName);
oilParams.localizedName = dm.GetItemLocalisationKeyName(oilName);
oilParams.localizedDescription = dm.GetItemLocalisationKeyName(oilName);
oilParams.sword = usedOnItem;
oilParams.maxCount = RoundMath(ammo);
oilParams.currCount = RoundMath(ammo);
oilParams.oilAbilityName = oilAbilities[0];
oilParams.oilItemName = oilName;
buffParams.buffSpecificParams = oilParams;

interactResult = AddEffectCustom(buffParams);
delete oilParams;

if ( interactResult == EI_Cancel || interactResult == EI_Undefined ) return false;

// recalculate applied oils and remove unwanted oil effects
oils = inv.GetActiveOilsAppliedOnItemCount(usedOnItem);

if ( !CanUseSkill(S_Alchemy_s06) ) A6level = 1;
else A6level = GetSkillLevel(S_Alchemy_s06);

if ( !GetWitcherPlayer() ) inv.RemoveAllOilsFromItem(usedOnItem);
else if ( oils > A6level )
for ( i=A6level; i<oils; i+=1 )

LogOils("Added oil <<" + oilName + ">> to <<" + inv.GetItemName(usedOnItem) + ">>");

if ( !inv.IsItemHeld(usedOnItem) ) PauseOilBuffs(inv.IsItemSteelSwordUsableByPlayer(usedOnItem));
return true;
CheckForPreviousLevelOilExploit(oilName,oils) - do we even need this now that effect processing works for oil levels? Need to look into that... Apparently not... can remove that entire function and CheckIfPreviousOilApplied() as well... :D

If you must know what EI_Cancel does, it decouples the logic for which effect was 'denied' previously... EI_Deny is now 'remove old effect, new is better' and EI_Cancel is 'cancel new effect, old is better'... part of something I fixed earlier, and allows you to correctly determine result via EEffectInteract. Without it, I suppose this would not be possible to begin with. Had to rework a bunch of effect logic.

---- Update: Well, that took longer than expected, may have fallen on my own sword after all, don't have time for this, but I fixed it, mostly... There are a bunch of issues with the way in which oils are handled. effect init params do not pass custom params. Oil effects are not separate but simply classifed under one W3Effect_Oil, which is problematic, especially combined with the fact they are applied to swords, which can be swapped to inventory, and there are mostly checks for slotted weapons only. Furthermore, I had to circumvent update time methods for Oil effects, and maybe set them inactive when ammo reaches zero, because it was removing the effects immediately after they were being applied.

Actually, I had to move all the S_Alchemy_s06 (Fixative Ability) code to ApplyEffect(), because of overridenEffectsIdxs... but it works better this way anyways. Much simpler, removing the oldest ones, so it doesn't mess up the QueueTimer index. More efficient than RemoveOldestOilFromItem():
oilEffect = (W3Effect_Oil)effects[overridenEffectsIdxs[ i ] ];
if ( oilEffect.GetQueueTimer() >= A6level )
RemoveEffectOnIndex( overridenEffectsIdxs[ i ], true );
Does this thing even work? LOL... in my tests it was only removing a single effect, because the array is ordered backwards... it adds the array from last to first, but then iterates from last to first, so it gets the lowest item in array, removes it, then fails the rest... haha.

In other words, cumulatIdx was only removing a single item... hehe... I guess that doesn't matter when each item can or 'should' (not reliable) apply only once... which is the case with all items, probably as a result of these bugs... fixed anyways...

edit: ah oh yes, I was just about to say, you can test this by using 'delete effects[overridenEffectsIdxs[ i ] ];'... ;p

Also, I had to hack in customItemUniqueId parameters for SCustomEffectParams and SEffectInitInfo (to pass the sword ref on init, for use in GetSelfInteraction). Not sure why this isn't by default, upon object initialization. Each item could then have effects, like crossbow bolts which curently lack them, and any inventory or character slot item. Currently I believe it's only on swords, but only in W3OilBuffParams, passed when the effect is created, not initialized. Obviously, that system would require a bit of work.

I can finally apply oils without ending up with 20 copies of the same thing, or 20 oils. :eek:

Well, I still have to test it a bit more, but Oils now seem to pass through the effects processor fine, and calculate 'fixative' skill level for removal of older oils. Inventory screen works fine as well. Sword swapping works fine, and Oils are set inActive correctly. Swords can be swapped to inventory and retain oils. Have to test stash still, saw there's some code for that, to remove the oils. Effects cumulate properly as well.
Last edited:
Top Bottom