Hi everyone,
A while back Pstemarie gave me this great script based on a script Mannast did (see below). I use it so my players can’t blast apart rocks with swords and other weapons only blunt weapons which makes sense. But now I have mining in an area and would like to use the light pick and heavy pick from the CEP in the script, but I can’t. The game does not recognize the CEP constants. I tried but could not get the script to compile:
//Checks if weapon used to damage was of an approved type or not. If not
//it then damages the weapon (with save)
//by Mannast May 2020
#include "x2_i0_spells"
//DoDamage takes the oItem and the nDamage and runs the saving throw. It will then return the damage amount
//which is dealt to the item in the void main()
int DoDamage(object oItem, int nDamage)
{
object oPC = GetItemPossessor(oItem);
int nDC = 10;//This is the base saving throw
int nSavMod;
int nSave;
string sItem = GetName(oItem);
//Set up saving throw for item targeted
if(GetIsMagicalItem(oItem)) nSavMod = nSavMod+5;//Is the item magical? If so, +5
if(GetIsItemPropertyValid(GetFirstItemProperty(oItem))!=FALSE) nSavMod = nSavMod+5;//Does it have at least one property? +5
//Do the saving throw
int nPlot=GetLocalInt(oItem, "Plot");
if(nPlot!=1) nSave = d20(1);
float fDelay2 = 0.3;
SendMessageToPC(oPC, "Weapon Saving Throw d20 "+IntToString(nSave)+" + Bonus "+IntToString(nSavMod)+" = "
+IntToString(nSave+nSavMod)+" against a DC of "+IntToString(nDC));
if((nSave+nSavMod)<nDC)
{
SendMessageToPC(oPC, "You damage your "+sItem+"! It takes "+IntToString(nDamage)+"!");
}
else
{
DelayCommand(fDelay2, FloatingTextStringOnCreature("The "+sItem+" has resisted the damage.", OBJECT_SELF));
}
return nDamage;
}
//MAIN script
void main()
{
object oPC = GetLastDamager();
object oItem = GetLastWeaponUsed(oPC);
int nType = GetBaseItemType(oItem);
int nDam = GetTotalDamageDealt();//Total Damage Dealt - this is apparently after Damage Reduction
int nItemHP = GetLocalInt(oItem, "Damaged");
if(nItemHP<=0)//If oItem has not been damaged before or if it hsn't been set.
{
nItemHP = GetLocalInt(GetModule(), "BASE_ITEM_HP");//can set this on the module
if(nItemHP==0) nItemHP = 20;//Base HP - to have a higher amount for specific items, set var int "Damaged" to desired number on item
if(GetIsMagicalItem(oItem)) nItemHP = nItemHP+5;//Is the item magical? If so, +5
if(GetIsItemPropertyValid(GetFirstItemProperty(oItem))!=FALSE) nItemHP = nItemHP+5;//Does it have at least one property? +5
}
if(nType==BASE_ITEM_WARHAMMER||nType==BASE_ITEM_MORNINGSTAR||nType==BASE_ITEM_LIGHTMACE||
nType==BASE_ITEM_LIGHTHAMMER||nType==BASE_ITEM_LIGHTFLAIL||nType==BASE_ITEM_HEAVYFLAIL||
nType==BASE_ITEM_DIREMACE||nType==BASE_ITEM_CLUB)//Edit these as you see fit - these were all the blunt objects I could find
{
SendMessageToPC(oPC, "Your weapon is doin' fine! Base Type = "+IntToString(nType));//Debug
return;//This damage is okay
}
else//All other types
{
int nHits = nDam;
int nDone = DoDamage(oItem, nHits);
nItemHP = nItemHP-nDone;
if(nItemHP<=0)//If item reaches zero at this point, it is destroyed
{
DestroyObject(oItem);
SendMessageToPC(oPC, "Your weapon is destroyed!");
//We could create a broken item here, but the PC would likely through it out - why do it then?
}
else
{
//Rename item to show it is damaged - also give (hp) info to show how it is doing.
string sDam = "Damaged ";
int nMin = 5;//Set this to where you want the PC informed their item is about to be destroyed
if(nItemHP<=nMin)
{
SendMessageToPC(oPC, "Your weapon is heavily damaged and won't take much more!");
sDam = "Heavily Damaged ";
}
SetLocalInt(oItem, "Damaged", nItemHP);//Put the new hps on the item
string sName = GetName(oItem);
string sOName = GetLocalString(oItem, "Name");
if(sOName=="") SetLocalString(oItem, "Name", sName);
else sName = sOName;
SetName(oItem, sDam+sName+" ("+IntToString(nItemHP)+" hps)");//Rename the damaged item
}
}
}
Can you edit the post so that the script is more readable first?
Better still, post just the line that isn’t compiling, or the constant you think is missing.
1 Like
You can (or better have to) define the CEP constants yourself. Or you could use the baseitems.2da row numbers directly.
if(nType==BASE_ITEM_WARHAMMER||nType==BASE_ITEM_MORNINGSTAR||nType==BASE_ITEM_LIGHTMACE||
nType==BASE_ITEM_LIGHTHAMMER||nType==BASE_ITEM_LIGHTFLAIL||nType==BASE_ITEM_HEAVYFLAIL||
nType==BASE_ITEM_DIREMACE||nType==BASE_ITEM_CLUB||nType==XYZ||nType==ABC)//Edit these as you see fit - these were all the blunt objects I could find
{
SendMessageToPC(oPC, “Your weapon is doin’ fine! Base Type = “+IntToString(nType));//Debug
return;//This damage is okay
}
with XYZ and ABC being the row numbers of light/heavy pick in baseitems.2da.
So if the row numbers are 301 and 302 it should look like
if(nType==BASE_ITEM_WARHAMMER||nType==BASE_ITEM_MORNINGSTAR||nType==BASE_ITEM_LIGHTMACE||
nType==BASE_ITEM_LIGHTHAMMER||nType==BASE_ITEM_LIGHTFLAIL||nType==BASE_ITEM_HEAVYFLAIL||
nType==BASE_ITEM_DIREMACE||nType==BASE_ITEM_CLUB||nType==301||nType==302)//Edit these as you see fit - these were all the blunt objects I could find
{
SendMessageToPC(oPC, “Your weapon is doin’ fine! Base Type = “+IntToString(nType));//Debug
return;//This damage is okay
}
1 Like
Hi andgalf,
Yeah…been a while since I posted a script and for the life of me…I forgot how to do that where it is readable. I thought it was putting the —> ` <---- tilde? before and after the script?
Hi Proleric,
It compiles as is…I just wanted to add the Constant for the heavy pick and light pick from the CEP, but the script won’t compile for example using the same line that Pstemarie used above for:
||nType==BASE_ITEM_HEAVYPICK||
for example....but I think I will try what Kamiryn suggested and get back to you all to see if it works.
Thanks Kamiryn…I will try what you suggest
I will get back to you with if it works or not.
You put three instead of two before and after.
1 Like
Ah…thanks andgalf…I fixed it now.
Did it work with Kamiryn’s suggestion?
Thanks Kamiryn!!
Works everyone.
Now one using this script as the baseline can make a script where only blunt weapons (or specific weapons like the Picks) can mine rock.
One can use only axes to cut trees (how stupid is it to have PCs cut trees down with swords?
Or you can make only hammers bust down doors and chests.
Thanks all of you for coming once again to my aid
I would post the script I did but I think some of my 2da lines might not match yours.
Consider this resolved
Oh…is there a way to make it so the PC can’t bash it with their hands OR to reduce the damage done by hands?
Because a light pick does 1d4 points while an unarmed attack almost does as much damage (1d3 for medium creatures). Perhaps penalize by 2 points. I think a penalty is good as monks could technically bash rocks with their bare hands and do more dame as they increase in level, but normal hands should not damage rocks.
EDIT: or…unarmed attacks/damage bounces back on PC. Whichever way is easier to script this. But this way…a monk will take more damage. Sigh…any other suggestions?
Hey Kamiryn,
Would you know what line to stick in this script to prevent unarmed attack so those PCs won’t use their hands to attack the rocks? Or even better,…if unarmed attack is used to make the damage dealt be rebounded back to the PC unless it is a monk. Is that possible?
Your script isn’t made for unarmed combat. To change that you have to check if actually a weapon was used and if not check if oPC has monk levels (or has the improved unarmed combat feat). Script should look like this then…
//MAIN script
void main()
{
object oPC = GetLastDamager();
object oItem = GetLastWeaponUsed(oPC);
if (GetIsObjectValid(oItem))
{
// a weapon was used (so no unarmed attack)
// rest of original main
// ...
}
else if is monk (or has improved unarmed strike feat)
{
SendMessageToPC(oPC, "You're a monk / you have the improved unarmed combat feat") // debug
return;
}
else // no monk (or no improved unarmed strike feat)
{
// do some damage to oPC
}
Thanks Kamiryn,
So do I add that to the top of the script I am using? I have put below the current script I put on the “OnDamaged” on my placeable:
//Checks if weapon used to damage was of an approved type or not. If not
//it then damages the weapon (with save)
//by Mannast May 2020
#include "x2_i0_spells"
//DoDamage takes the oItem and the nDamage and runs the saving throw. It will then return the damage amount
//which is dealt to the item in the void main()
int DoDamage(object oItem, int nDamage)
{
object oPC = GetItemPossessor(oItem);
int nDC = 15;//This is the base saving throw
int nSavMod;
int nSave;
string sItem = GetName(oItem);
//Set up saving throw for item targeted
if(GetIsMagicalItem(oItem)) nSavMod = nSavMod+5;//Is the item magical? If so, +5
if(GetIsItemPropertyValid(GetFirstItemProperty(oItem))!=FALSE) nSavMod = nSavMod+5;//Does it have at least one property? +5
//Do the saving throw
int nPlot=GetLocalInt(oItem, "Plot");
if(nPlot!=1) nSave = d20(1);
float fDelay2 = 0.3;
SendMessageToPC(oPC, "Weapon Saving Throw d20 "+IntToString(nSave)+" + Bonus "+IntToString(nSavMod)+" = "
+IntToString(nSave+nSavMod)+" against a DC of "+IntToString(nDC));
if((nSave+nSavMod)<nDC)
{
SendMessageToPC(oPC, "You damage your "+sItem+" because only picks or blunt weapons work on this! It takes "+IntToString(nDamage)+"!");
}
else
{
DelayCommand(fDelay2, FloatingTextStringOnCreature("The "+sItem+" has resisted the damage.", OBJECT_SELF));
}
return nDamage;
}
//MAIN script
void main()
{
object oPC = GetLastDamager();
object oItem = GetLastWeaponUsed(oPC);
int nType = GetBaseItemType(oItem);
int nDam = GetTotalDamageDealt();//Total Damage Dealt - this is apparently after Damage Reduction
int nItemHP = GetLocalInt(oItem, "Damaged");
if(nItemHP<=0)//If oItem has not been damaged before or if it hsn't been set.
{
nItemHP = GetLocalInt(GetModule(), "BASE_ITEM_HP");//can set this on the module
if(nItemHP==0) nItemHP = 20;//Base HP - to have a higher amount for specific items, set var int "Damaged" to desired number on item
if(GetIsMagicalItem(oItem)) nItemHP = nItemHP+5;//Is the item magical? If so, +5
if(GetIsItemPropertyValid(GetFirstItemProperty(oItem))!=FALSE) nItemHP = nItemHP+5;//Does it have at least one property? +5
}
if(nType==BASE_ITEM_WARHAMMER||BASE_ITEM_LIGHTHAMMER||
nType==nType==318||nType==510||
nType==nType==301||nType==302)//Edit these as you see fit - these were all the blunt objects I could find
{
SendMessageToPC(oPC, "Your weapon is doin' fine! Base Type = "+IntToString(nType));//Debug
return;//This damage is okay
}
else//All other types
{
int nHits = nDam;
int nDone = DoDamage(oItem, nHits);
nItemHP = nItemHP-nDone;
if(nItemHP<=0)//If item reaches zero at this point, it is destroyed
{
DestroyObject(oItem);
SendMessageToPC(oPC, "Your weapon is destroyed!");
//We could create a broken item here, but the PC would likely through it out - why do it then?
}
else
{
//Rename item to show it is damaged - also give (hp) info to show how it is doing.
string sDam = "Damaged ";
int nMin = 5;//Set this to where you want the PC informed their item is about to be destroyed
if(nItemHP<=nMin)
{
SendMessageToPC(oPC, "Your weapon is heavily damaged and won't take much more!");
sDam = "Heavily Damaged ";
}
SetLocalInt(oItem, "Damaged", nItemHP);//Put the new hps on the item
string sName = GetName(oItem);
string sOName = GetLocalString(oItem, "Name");
if(sOName=="") SetLocalString(oItem, "Name", sName);
else sName = sOName;
SetName(oItem, sDam+sName+" ("+IntToString(nItemHP)+" hps)");//Rename the damaged item
}
}
}
So I tried to blend both the script above you helped me with plus this update and got this:
So here is that full script where it has that error:
//"weapon_chk" OnDamage script for plaeables
//Checks if weapon used to damage was of an approved type or not. If not
//it then damages the weapon (with save)
//by Mannast May 2020
#include "x2_i0_spells"
//MAIN script
void main()
{
object oPC = GetLastDamager();
object oItem = GetLastWeaponUsed(oPC);
if (GetIsObjectValid(oItem))
{
// a weapon was used (so no unarmed attack)
//DoDamage takes the oItem and the nDamage and runs the saving throw. It will then return the damage amount
//which is dealt to the item in the void main()
int DoDamage(object oItem, int nDamage)
{
object oPC = GetItemPossessor(oItem);
int nDC = 15;//This is the base saving throw
int nSavMod;
int nSave;
string sItem = GetName(oItem);
//Set up saving throw for item targeted
if(GetIsMagicalItem(oItem)) nSavMod = nSavMod+5;//Is the item magical? If so, +5
if(GetIsItemPropertyValid(GetFirstItemProperty(oItem))!=FALSE) nSavMod = nSavMod+5;//Does it have at least one property? +5
//Do the saving throw
int nPlot=GetLocalInt(oItem, "Plot");
if(nPlot!=1) nSave = d20(1);
float fDelay2 = 0.3;
SendMessageToPC(oPC, "Weapon Saving Throw d20 "+IntToString(nSave)+" + Bonus "+IntToString(nSavMod)+" = "
+IntToString(nSave+nSavMod)+" against a DC of "+IntToString(nDC));
if((nSave+nSavMod)<nDC)
{
SendMessageToPC(oPC, "You damage your "+sItem+" because only picks or blunt weapons work on this! It takes "+IntToString(nDamage)+"!");
}
else
{
DelayCommand(fDelay2, FloatingTextStringOnCreature("The "+sItem+" has resisted the damage.", OBJECT_SELF));
}
return nDamage;
}
}
}
Your last script looks really weird. The int DoDamage(object oItem, int nDamage) is a separate function that returns an integer. You need that outside of the void main first, like in the script you posted above this last one. Then you need to call the function inside the void main (also like you did in the script you posted above the last one). You can’t just put the new function inside the if statement like that.
Huh?..lol…
O.O
LOL…bud…I don’t know what you just said. I just put the first script into Kamiryn’s script where I thought he said to:
// rest of original main
// ...
So I thought that is how it should be. Could you do the scripts together for me to show me what you mean andgalf?