Well
If using nwnx - yes, you can hook and 'somewhat' override the creature that is summed.
The thing to remember is that Summon Creature takes an int input. (It then translates that int to the string via 2da lookups)
So, normal hooking in nwnx would only really allow you to swap that int value with another int value, it would still require that string value to exist in the 2da.
The alternative, is to actually replace the SummonCreature method, with your own implementation.
This is still achieved via a hook, but instead of connecting the hook up to the original method, you would just abandon the execution and return your success value.
Below is an example hook/replacement of SummonAnimalCompanion
void __fastcall CNWSCreature__SummonAnimalCompanion( CNWSCreature * cre, void*){
ResetParameters( );
CResRef resref;
std::fill_n(resref.resref, 16, 0);
int32_t level = cre->cre_stats->GetNumLevelsOfClass(3); //Druid
level += cre->cre_stats->GetNumLevelsOfClass(7); //Ranger
if ( level <= 0 ) {
return;
}
else if ( level > 40 ) {
level = 40;
}
nwn_objid_t assoc_id = cre->GetAssociateId(2, 1);
CNWSCreature *assoc = NULL;
if ( assoc_id != OBJECT_INVALID &&
(assoc = (*NWN_AppManager)->app_server->srv_internal->GetCreatureByGameObjectID(assoc_id)) != NULL ) {
assoc->ReceiveAssociateCommand(-8);
}
C2DA *fam2da = (*NWN_Rules)->ru_2das->tda_hen_companion;
CExoString famResRef;
int familiar_type = cre->cre_stats->cs_acomp_type;
fam2da->GetCExoStringEntry(familiar_type, "BASERESREF", &famResRef); <-- This is when the 2da is actually used to acquire the resref, changing the resref here is sorta along the lines of where you would want to change it.
if ( level > 9 ) {
sprintf( resref.resref, "%s%d", famResRef.text, level );
//snprintf(resref.resref, 16, "%s%d", base, level);
}
else {
sprintf( resref.resref, "%s0%d", famResRef.text, level );
//snprintf(resref.resref, 16, "%s0%d", base, level);
}
for ( size_t i = 0; i < 16; ++i ) {
resref.resref[i] = tolower(resref.resref[i]);
}
char *name = new char[250];
sprintf( name, "%.250s", cre->cre_stats->cs_acomp_name );
cre->SummonAssociate(resref,name,2);
assoc_id = cre->GetAssociateId(2, 1);
Cool.Event = 104;
Cool.oTarget = cre->obj.obj_generic.obj_id;
Cool.oTarget2 = assoc_id;
Cool.Log( 1, "o Summon Animal Companion: %08lx %08lx \n", cre, assoc_id );
Cool.ScriptRunning = true;
(*NWN_VirtualMachine)->Runscript(&CExoString("nwnx_cool"), cre->obj.obj_generic.obj_id);
Cool.ScriptRunning = false;
//cre->cre_ = 1;
}
Summons are a bit annoying in that they don't return the object after the effect is fired.
Eg:
You cannot do
object myCreature = SummonCreature("myUnicorn");
This is why there isn't generally any native nwn means of enhancing summons, without using nwnx.
The alternative, which is somewhat native, is to not use EffectSummonCreature(), and instead create your own custom framework that works around creating creatures, and adding them to the faction of the summoner.
If you have access to some nwnx plugins such as funcs and perhaps cool, you can set the faction, change their ability score and scripts, and set their association to the player.
So you can simulate summoning, but achieve much more functionality and flexibility than using the inbuilt summoning system.