![]() |
e_Carnivores - Making Carnivores hunt - Printable Version +- SphereCommunity (https://forum.spherecommunity.net) +-- Forum: Sphere 0.56d (/Forum-Sphere-0-56d) +--- Forum: Script Submissions (/Forum-Script-Submissions) +--- Thread: e_Carnivores - Making Carnivores hunt (/Thread-e-Carnivores-Making-Carnivores-hunt) |
e_Carnivores - Making Carnivores hunt - Capes - 03-17-2018 10:36 PM Alright - since this community has been very helpful in answering my many questions regarding how sphere works and such, I am submitting my first script. Please feel free to critique! 0.56d nightly. Info - I noticed events in sphere_event_npcs.scp like e_Carnivores,e_Carnivores2 & e_Carnivores3 were blank, and in the corresponding sphere_monsters.scp file all the code was already there for critters to be carnivores. This is my attempt to make animals hunt when hungry, provided that they are carnivores (if they have TEVENTS in their CHARDEF defined as e_Carnivores). This only effects animals. 1) Global variable (placed in sphere_serv_triggers.scp under [FUNCTION f_onserver_start]) VAR.HUNGER_RATE_DECAY_TIME = 120 ///////////////////////////////////////////////////// ///// VAR.HUNGER_RATE_DECAY_TIME = 120 //// (in secs) //// 120 = every 2 mins at 20 mins per day cycle or reduced 10 times a day //// so critter with maxfood=10 will eat once a day ///////////////////////////////////////////////////// 2) Modified sphere_events_npc.scp [EVENTS]e_Carnivores,e_Carnivores2,e_Carnivores3 just like below [EVENTS e_Carnivores] // weak carnivores. ON=@CREATE EVENTS +e_Hunger f_setNeedsFood [EVENTS e_Carnivores2] // normal carnivores. ON=@CREATE EVENTS +e_Hunger f_setNeedsFood [EVENTS e_Carnivores3] // strong carnivores. ON=@CREATE EVENTS +e_Hunger f_setNeedsFood 3) Added this to the bottom of sphere_events_npc.scp ///////////////////////////////////////////////////// //// EVENT e_Hunger //// -our event handler for ON=@ HUNGER/KILL/DEATH //// -only executes when (hunger_in_effect) is set on animal //// -1)sets a new brain to animal and possible buff/debuff based on e__Carnivores TEVENTS //// -2)resets brain to animal after killing (eating) so it doesn't hunt anymore //// -3)cleans up mem from tags ///////////////////////////////////////////////////// [EVENTS e_Hunger] ON=@HUNGER //<-- triggered from f_Hunger_handler IF !(<eval <I.TAG.hunger_in_effect>>) return //no hunger_in_effect so quit ENDIF //change brain and do something special for given e_Carnivore's type IF ((STRCMPI(<I.TEVENTS>,e_Carnivores)==0) || (STRCMPI(<I.TEVENTS>,e_Carnivores)==1))) //we are e_Carnivores (weak), do something ELSEIF ((STRCMPI(<I.TEVENTS>,e_Carnivores2)==0) || (STRCMPI(<I.TEVENTS>,e_Carnivores2)==1))) //we are e_Carnivores2 (normal), do something ELSEIF ((STRCMPI(<I.TEVENTS>,e_Carnivores3)==0) || (STRCMPI(<I.TEVENTS>,e_Carnivores3)==1))) //we are e_Carnivores3 (strong), do something ENDIF //we are hungry attack something (change brain) I.NPC = brain_berserk ON=@KILL //<-- triggered after any kill IF !(<eval <I.TAG.hunger_in_effect>>) return //no hunger_in_effect so quit ENDIF //change back to animal brain, reset hunger lvl and restart timer I.NPC = brain_animal I.TAG.hunger_lvl =<eval <I.FOOD>> I.TIMERF <eval <VAR.HUNGER_RATE_DECAY_TIME>> f_Hunger_handler ON=@DEATH IF !(<eval <I.TAG.hunger_in_effect>>) return //no hunger_in_effect so quit ENDIF //clear hunger lvl tag & hunger in effect from mem I.TAG.hunger_lvl = I.TAG.hunger_in_effect = ///////////////////////////////////////////////////// //// FUNCTION f_setNeedsFood //// -prevents usage if not brain_animal (must be an animal) //// -set hunger lvl & hunger in effect tags //// -starts our hunger handler ///////////////////////////////////////////////////// [FUNCTION f_setNeedsFood] //only do if this is an animal //set variable to store hunger level & set var to show hunger is in effect & start timer IF (<NPC> == brain_animal) TAG.hunger_lvl = <eval <FOOD>> //prevents other scripts from triggering our events TAG.hunger_in_effect = 1 TIMERF <eval <VAR.HUNGER_RATE_DECAY_TIME>> f_Hunger_handler ENDIF ///////////////////////////////////////////////////// //// FUNCTION f_Hunger_handler //// -recursive routine //// -reduces hunger lvl by 1 each interval //// -stops loop and fires @HUNGER event of e_Hunger (events) above ///////////////////////////////////////////////////// [FUNCTION f_Hunger_handler] //reduce hunger lvl I.TAG.hunger_lvl -= 1 //if hungry fire hunger trigger and exit otherwise run timer-func again IF (<eval <I.TAG.hunger_lvl>> <= 0) //trigger hunger event I.TRIGGER @HUNGER return ENDIF TIMERF <eval <VAR.HUNGER_RATE_DECAY_TIME>> f_Hunger_handler ///////////////////////////////////////////////////// I have left room for adding other behaviors in [EVENTS e_Hunger] if desired. Now I never know if that dam bear is gunna attack me or not! Thanks to everyone! Capes RE: e_Carnivores - Making Carnivores hunt - n1ghtwish - 03-21-2018 03:11 AM Thank you for taking the time to post your first script!!! I have not tested it but I do have a few suggestions 1) You don't need to use "I" as the default object... it works, but you can remove it and instead of "I.tag.blah = 123" you can simply do "tag.blah = 123" 2) VAR.HUNGER_RATE_DECAY_TIME = 120 Instead of storing your time in a GLOBAL variable, it is now common practice to store "setting" type variables in a DEFNAME block. Example: Code: [DEFNAME hunger_settings] Then you access it later with "<DEF.HUNGER_RATE_DECAY_TIME>" 3) Do some research on adding a ZERO to TAGS, DEFS, VARS, etc... example: <tag0.something>, <def0.something> Might help with console error reduction ![]() 4) Look into the "ISEVENT" property/function 5) "<dTAG.hunger_in_effect>" is essentially a shortcut for "<eval <I.TAG.hunger_in_effect>>", the "d" being placed in front of the TAG automatically returns said tag (or var or def or whatever) in decimal format, which is what EVAL does. In your line "IF !(<eval <I.TAG.hunger_in_effect>>)" it is not necessarily required to evaluate the tag if you are simply checking to see if it exists. -------------------------- Also, I appreciate your commenting on each block of the script... most don't do that and it will help others with installation and tailoring ![]() -NW RE: e_Carnivores - Making Carnivores hunt - Capes - 03-25-2018 05:21 AM Thank you n1ghtwish! Based on your suggestions I have made some changes. - No longer am I modifying sphere_*.scp files directly. Instead all code is gunna be in a customs folder, that will override the original sphere_*.scp files. To make this work - create a file.scp (call it what you want), place it in a custom folder, make sure sphere_tables.scp reflects & reads the folder/file last. Copy/paste below into that file. Restart server. //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //// EVENT OVERRIDES //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////// ///// HUNGER_RATE_DECAY_TIME = 120 //// (in secs) //// 120 = every 2 mins at 20 mins per day cycle or reduced 10 times a day //// so critter with mxfood=10 will eat once a day ///////////////////////////////////////////////////// [DEFNAME hunger_settings] HUNGER_RATE_DECAY_TIME = 120 [EVENTS e_Carnivores] // weak carnivores. ON=@CREATE EVENTS +e_Hunger f_setNeedsFood [EVENTS e_Carnivores2] // normal carnivores. ON=@CREATE EVENTS +e_Hunger f_setNeedsFood [EVENTS e_Carnivores3] // strong carnivores. ON=@CREATE EVENTS +e_Hunger f_setNeedsFood ///////////////////////////////////////////////////// //// EVENT e_Hunger //// -our event handler for ON=@ HUNGER/KILL/DEATH //// -only executes when (hunger_in_effect) is set on animal //// -1)sets a new brain to animal and possible buff/debuff based on e__Carnivores EVENTS //// -2)resets brain to animal after killing (eating) so it doesn't hunt anymore //// -3)cleans up mem from tags ///////////////////////////////////////////////////// [EVENTS e_Hunger] ON=@HUNGER //<-- triggered from f_Hunger_handler IF !(<dTAG0.hunger_in_effect>) return //no hunger_in_effect so quit ENDIF //change brain and do something special for given e_Carnivore's type IF (<TEVENTS> & e_Carnivores) //we are e_Carnivores (weak), do something ELSEIF (<TEVENTS> & e_Carnivores2) //we are e_Carnivores2 (normal), do something ELSEIF (<TEVENTS> & e_Carnivores3) //we are e_Carnivores3 (strong), do something ENDIF //we are hungry attack something NPC = brain_berserk ON=@KILL //<-- triggered after any kill IF !(<dTAG0.hunger_in_effect>) return //no hunger_in_effect so quit ENDIF //change back to animal brain, reset hunger lvl and restart timer NPC = brain_animal TAG0.hunger_lvl =<eval <FOOD>> TIMERF <dDEF.HUNGER_RATE_DECAY_TIME> f_Hunger_handler ON=@DEATH IF !(<dTAG0.hunger_in_effect>) return //no hunger_in_effect so quit ENDIF //clear hunger lvl tag & hunger in effect from mem TAG0.hunger_lvl = TAG0.hunger_in_effect = ///////////////////////////////////////////////////// //// FUNCTION f_setNeedsFood //// -prevents usage if not brain_animal (must be an animal) //// -set hunger lvl & hunger in effect tags //// -starts our hunger handler ///////////////////////////////////////////////////// [FUNCTION f_setNeedsFood] //only do if this is an animal //set variable to store hunger level & set var to show hunger is in effect & start timer IF (<NPC> == brain_animal) TAG0.hunger_lvl = <eval <FOOD>> //prevents other scripts from triggering our events TAG0.hunger_in_effect = 1 TIMERF <dDEF.HUNGER_RATE_DECAY_TIME> f_Hunger_handler ENDIF ///////////////////////////////////////////////////// //// FUNCTION f_Hunger_handler //// -recusive routine //// -reduces hunger lvl by 1 each interval //// -stops recursing and fires @HUNGER event of e_Hunger (events) above ///////////////////////////////////////////////////// [FUNCTION f_Hunger_handler] //reduce hunger lvl TAG0.hunger_lvl -= 1 //if hungry fire hunger trigger and exit otherwise run timer-func again IF (<dTAG0.hunger_lvl> == 0) //trigger hunger event TRIGGER @HUNGER return ENDIF TIMERF <dDEF.HUNGER_RATE_DECAY_TIME> f_Hunger_handler ///////////////////////////////////////////////////// Thanks Capes PS- it was suggested that ISEVENT be used but that only works on EVENTS added in ON=@CREATE of chardef, and TEVENTS is a separate list so I was forced to use (<TEVENTS> & e_Carnivores2). |