AIP Actions

Tools for osRose and osiRose will be placed in here, as well as Rose file formats.

Please PM rl2171 or lmame to get them added to the list.

Moderators: osRose dev team, ospRose dev team, osiRose dev team, Moderators

Re: AIP Actions

Postby PurpleYouko on Tue Jun 04, 2019 2:34 pm

AIP_REWD_020

  1. //Spawn Monster
  2. AIP_REWD_020
  3.     uint16 cMonster         //Byte 0
  4.     uint8 btPos             //Byte 2
  5.     uint32 iDistance        //byte 4
  6.     //Spawn cMonster within iDistance of btPos
  7.     CMap* map = GServer->MapList.Index[entity->Position->Map]       //get the map
  8.     if(btPos == 0)                                                  //My position
  9.         position = Rose::Math::RandInCircle( entity->Position->current, iDistance ) //get random point in a circle
  10.         map->AddMonster( cMonster, position, 0)                     //Add the monster to the map
  11.     else if(btPos == 1)                                             //My Attacker's position
  12.         CCharacter* attacker = entity->getCharAttacker ( )          //Get my attacker
  13.         if (attacker == NULL )                                      //Can't find attacker. return
  14.             return AI_SUCCESS
  15.         position = Rose::Math::RandInCircle( entity->Position->current, iDistance ) //get random point in a circle
  16.         map->AddMonster( cMonster, position, 0 )                    //Add the monster to the map
  17.     else if(btPos == 2)                                             //my current Target's position
  18.         CCharacter* target = entity->getCharTarget( )               //get target
  19.         if ( target == NULL )                                       //nope! returning
  20.             return AI_SUCCESS
  21.         position = Rose::Math::RandInCircle( target->Position->current, iDistance ) //get random point in a circle
  22.         map->AddMonster( cMonster, position, 0 )                    //Add the monster to the map
  23.     return AI_SUCCESS


Another monster spawner.
Spawns one monster of type 'cMonster' in a circle of radius 'iDistance' around a location defined by btPos where 0 = My current position, 1 = My attacker's current positions or 2 = My current Target's current position
Need to lookup information on NARose items, skills, quests?
Now featuring a newly completed skill tree for all classes
Formatting fixed for different resolutions
Image

"A Gazelle is nothing but a giraffe plotted logarithmicaly"
User avatar
PurpleYouko
Rose Guru
Rose Guru
 
Posts: 4733
Joined: Fri Aug 10, 2007 2:05 pm

Re: AIP Actions

Postby PurpleYouko on Tue Jun 04, 2019 2:46 pm

AIP_REWD_021

  1. //Not Used
  2. AIP_REWD_021
  3.     //As noted above NOT USED!
  4.     return AI_SUCCESS


AIP_REWD_022

  1. //Not Used
  2. AIP_REWD_022
  3.     //As noted above NOT USED!
  4.     return AI_SUCCESS


Really!! That's what the server code actually says in the SHO server. Here is the original korean if you don't believe me
  1. void F_AIACT21 (stActHead *pActDATA, t_AIPARAM *pEVENT)    
  2. {   
  3.     // 사용 안함.
  4. }
  5. void F_AIACT22 (stActHead *pActDATA, t_AIPARAM *pEVENT)    
  6. {   
  7.     // 사용 안함.
  8. }
Need to lookup information on NARose items, skills, quests?
Now featuring a newly completed skill tree for all classes
Formatting fixed for different resolutions
Image

"A Gazelle is nothing but a giraffe plotted logarithmicaly"
User avatar
PurpleYouko
Rose Guru
Rose Guru
 
Posts: 4733
Joined: Fri Aug 10, 2007 2:05 pm

Re: AIP Actions

Postby PurpleYouko on Tue Jun 04, 2019 2:52 pm

AIP_REWD_023

  1. //Suicide
  2. AIP_REWD_023
  3.     entity->Stats->HP = -1                                              // Set my own HP to -1
  4.     CPacket pak     ( 0x0799 )                                          // Start a damage packet
  5.     pak.addUINT16   ( entity->clientid )                                // The Attacker
  6.     pak.addUINT16   ( entity->clientid )                                // The Defender (myself in this case)
  7.     pak.addUINT32   ( entity->thisnpc->hp * entity->thisnpc->level )    // Damage. has to be __int64
  8.     pak.addUINT32   ( DMG_ACT_DEAD )                                    // including switches. DMG_ACT_DEAD is defined as 16
  9.     GServer->SendToVisible( &pak, entity )
  10.     return AI_SUCCESS


As noted in the code, this function allows a monster to kill itself.
Used for things such as a summon ending it's own life either when it times out or when its master is either dead or has left the map
Need to lookup information on NARose items, skills, quests?
Now featuring a newly completed skill tree for all classes
Formatting fixed for different resolutions
Image

"A Gazelle is nothing but a giraffe plotted logarithmicaly"
User avatar
PurpleYouko
Rose Guru
Rose Guru
 
Posts: 4733
Joined: Fri Aug 10, 2007 2:05 pm

Re: AIP Actions

Postby PurpleYouko on Tue Jun 04, 2019 3:01 pm

AIP_REWD_024

  1. //Do Skill
  2. AIP_REWD_024
  3.     uint8 btTarget      //Byte 0
  4.     uint16 nSkill       //Byte 2
  5.     uint16 nMotion      //Byte 4     Skill type as used in the STB
  6.  
  7.     //Use nSkill & nMotion?
  8.     //btTarget 0 = m_pFindCHAR
  9.     //btTarget 1 = target
  10.     //btTarget 2 = self skill
  11.    
  12.     CSkills* thisskill = GServer->GetSkillByID( nSkill )        //Initialize the skill
  13.     if(thisskill == NULL)                                       //failed so return
  14.         return AI_SUCCESS
  15.     CCharacter* target = NULL                                   //Initialize target
  16.     if ( btTarget == 0 )                                        //Uses findChar as the target
  17.         CCharacter* target = GServer->GetClientByID ( entity->findChar, entity->Position->Map )
  18.         if ( target == NULL )                                   //failed so return
  19.             return AI_SUCCESS
  20.     else if (btTarget == 1)                                     //Uses current target
  21.         target = entity->getCharTarget ( )     
  22.         if ( target == NULL )                                   //failed so return
  23.             return AI_SUCCESS
  24.     else if ( btTarget = 2 )                                    //Uses myslef (self skill)
  25.         target = entity
  26.     entity->CurrentAction->AnimationType = nMotion              //Set up the skill animation type for StartAction to process.
  27.     entity->StartAction ( target, nSkill )                      //Start the action
  28.     return AI_SUCCESS


Monster uses a skill
btTarget defines the target type. 0 = findChar. 1 = current target. 2 =self
nSkill is the skill id from LIST_SKILL.STB
nMotion is the animation type to use
Need to lookup information on NARose items, skills, quests?
Now featuring a newly completed skill tree for all classes
Formatting fixed for different resolutions
Image

"A Gazelle is nothing but a giraffe plotted logarithmicaly"
User avatar
PurpleYouko
Rose Guru
Rose Guru
 
Posts: 4733
Joined: Fri Aug 10, 2007 2:05 pm

Re: AIP Actions

Postby PurpleYouko on Tue Jun 04, 2019 4:17 pm

AIP_REWD_025

  1. //Set or modify ObjVar Variable
  2. AIP_REWD_025
  3.     uint16 nVarno       //Byte 0
  4.     uint32 iValue       //Byte 4
  5.     uint8 btOp          //Byte 8
  6.    
  7.     if ( nVarno > 19 )                      //only 20 ( 0 ~ 19 ) addresses available
  8.         return AI_SUCCESS
  9.     if(entity->thisnpc->refNPC >= MAX_NPC)  //MAX_NPC should coroespond to the size of your LIST_NPC.STB file
  10.         return AI_SUCCESS
  11.     short tempval = GServer->ObjVar[entity->thisnpc->refNPC][nVarno] //temporary holder for current ObjVar value
  12.  
  13.     switch(btOp)                            // So what to do with the current value in the ObjVar array
  14.         case 5:
  15.             tempval = iValue                // Overwrite it with iValue
  16.         case 6:
  17.             tempval += iValue               // add iValue to it
  18.         case 7:
  19.             tempval -= iValue               // subtract iValue from it
  20.         case 9:
  21.             tempval++                       // increment it
  22.         default:                            // or maybe btOp was not one of the usable values so do nothing
  23.             return AI_SUCCESS
  24.     if(tempval < 0)                         // Make sure tempval stays >= 0
  25.         tempval = 0
  26.     GServer->ObjVar[entity->thisnpc->refNPC][nVarno] = tempval  // Save tempval back into the ObjVar
  27.    
  28.     return AI_SUCCESS


This one is quite versatile. We can use it for several things.
Basically though it is used to set or modify one of the 20 possible ObjVar variables for refNPC (selected in conditions).
As you may remember ObjVar is a 2 dimensional array with the first index being address by the entity's currently set refNPC variable which we set up in one of the conditions. refNPC is persistent in that it remains set for the lifetime of an entity or until it is overwritten by another AIP condition.
So that means that every NPC (technically every monster type but there are only ever one of each NPC type in the world at any given time) has an array of 20 values that can be stored and manipulated
What makes this so versatile is that a number of the positions in this 20 number array have extra-curricular activities. i.e. they have direct effects on the world other than just storing things like current world states.
element 0 is extremely special. It represents the NPCs eventID
If you set this one to some new value then you will actively be changing the entire event.
Example.
Good old Judy in Zant. She controls tons of events
so for events connected to Judy we would be looking at ObjVar[1201][0]
if this value is zero then she just gives you the default scripts and tells you that nothing much is going on right now.
if you set it to 101 though.... That starts the summer event so when you talk to her she will say
Hello, <NAME>. Do you have any plans for this summer vacation?

and then send you off to the sunshine coast to clean up the beach by collecting trash. She will also trade that trash for all kinds of goodies.

All that just by setting one simple ObjVar value using a refNPC of 1201

Wanna start the world cup soccer event? Set it to 308

the only problem in all this is that in the standard osrose servers there is no direct link between element 0 and the event id. The AIP will still make it work but the code uses special case scenarios rather than directly connecting the dots.

Element 2 is rumored to be special as well in certain cases.
if we set ObjVar [1113][2] it can trigger something related to union wars. That's [Referee] Leum in case you were wondering. This is far from fully coded out though so don't expect it to just work if you set that value
Need to lookup information on NARose items, skills, quests?
Now featuring a newly completed skill tree for all classes
Formatting fixed for different resolutions
Image

"A Gazelle is nothing but a giraffe plotted logarithmicaly"
User avatar
PurpleYouko
Rose Guru
Rose Guru
 
Posts: 4733
Joined: Fri Aug 10, 2007 2:05 pm

Re: AIP Actions

Postby PurpleYouko on Tue Jun 04, 2019 4:44 pm

AIP_REWD_026

  1. //Set Variable (2)
  2. AIP_REWD_026
  3.     //Set WorldVAR
  4.     uint16 nVarno       //Byte 0
  5.     uint32 iValue       //Byte 4
  6.     uint8 btOp          //Byte 8   
  7.     //PY: we don't know how to use worldVar so here are some fun things we could potentially do with custom AI
  8.     switch(nVarno)
  9.         case 1: //change world exp rate in the config
  10.             GServer->Config.EXP_RATE = iValue
  11.             return AI_SUCCESS
  12.         case 2: // change world or map droprate in the config
  13.             return AI_SUCCESS
  14.         default:
  15.             return AI_SUCCESS


This is just an idea of what i would possibly like to do with this function.
What it actually does in SHO is to modify world time. This is one of the functions related to it if you are interested.
  1. void Reset_WorldVAR (BYTE *pVAR)
  2.     {
  3.         ::CopyMemory( m_pVAR, pVAR, sizeof( tagWorldVAR ) );
  4.  
  5.         short nYear, nMonth, nDay;
  6.         nYear  = (short)( m_dwAccTIME / TIME_PER_YEAR );
  7.         nMonth = (short)( (m_dwAccTIME - (nYear*TIME_PER_YEAR) ) / TIME_PER_MONTH + 1 );
  8.         nDay   = (short)( (m_dwAccTIME - (nYear*TIME_PER_YEAR) - TIME_PER_MONTH*(nMonth-1) ) / 160 + 1 );
  9.  
  10.         m_nWorldVAR[ WORLD_VAR_YEAR  ] = nYear;
  11.         m_nWorldVAR[ WORLD_VAR_MONTH ] = nMonth;
  12.         m_nWorldVAR[ WORLD_VAR_DAY   ] = nDay;
  13.         m_nWorldVAR[ WORLD_VAR_TIME  ] = (short)( m_dwAccTIME % TIME_PER_MONTH );
  14.     }

I have not found a single AIP file that uses this function so it's not really a lot of use in it's present format so feel free to use it as a custom function if you feel that way inclined.
My own plan is to use it to control things like global and map EXP and Drop rates based on various events which I plan to build.
Need to lookup information on NARose items, skills, quests?
Now featuring a newly completed skill tree for all classes
Formatting fixed for different resolutions
Image

"A Gazelle is nothing but a giraffe plotted logarithmicaly"
User avatar
PurpleYouko
Rose Guru
Rose Guru
 
Posts: 4733
Joined: Fri Aug 10, 2007 2:05 pm

Re: AIP Actions

Postby PurpleYouko on Tue Jun 04, 2019 4:48 pm

AIP_REWD_027

  1. //Set Variable (3)
  2. AIP_REWD_027
  3.     //Set EconomyVAR
  4.     uint16 nVarno       //Byte 0
  5.     uint32 iValue       //Byte 4
  6.     uint8 btOp          //Byte 8
  7.     return AI_SUCCESS


Same sort of thing again but this time related to Economy variables.

Even SHO code doesn't go into this in any detail
  1. void CObjCHAR::Set_EconomyVAR(short nVarIDX, int iValue)
  2. {
  3. #pragma COMPILE_TIME_MSG ( "TODO:: CObjCHAR::Set_EconomyVAR(short nVarIDX, int iValue) " )
  4. }

Apparently it just prints out a reminder message telling them that they still have to figure this shit out. Well they never did because not one single AIP file calls this function
Need to lookup information on NARose items, skills, quests?
Now featuring a newly completed skill tree for all classes
Formatting fixed for different resolutions
Image

"A Gazelle is nothing but a giraffe plotted logarithmicaly"
User avatar
PurpleYouko
Rose Guru
Rose Guru
 
Posts: 4733
Joined: Fri Aug 10, 2007 2:05 pm

Re: AIP Actions

Postby PurpleYouko on Tue Jun 04, 2019 5:14 pm

AIP_REWD_028

  1. //Shout/Ann LTB String
  2. AIP_REWD_028
  3.     uint8 btMsgType         //Byte 0
  4.     uint32 iStrID           //Byte 4
  5.     dword npcId = 0;
  6.  
  7.     if(iStrID >= GServer->maxltbaip)        //Just making sure that the reference isn't off the end of the LTB files that we loaded
  8.         return AI_SUCCESS
  9.     switch(btMsgType)
  10.         case 0: //say something in chat
  11.             if ( entity->thisnpc->refNPC != 0 )         //Make NPC referenced in refNPC speak to the map
  12.                 GServer->NPCSpeak ( entity, GServer->Ltbstring[iStrID]->LTBstring, GServer->GetSTLMonsterNameByID ( entity->thisnpc->refNPC ))
  13.             else                                        //Make this entity speak to the map
  14.                 GServer->NPCSpeak ( entity,GServer->Ltbstring[iStrID]->LTBstring,GServer->GetSTLMonsterNameByID(entity->aip_npctype))
  15.         case 1: //shout to map
  16.             if ( entity->thisnpc->refNPC != 0 )         //Make NPC referenced in refNPC shout to the map
  17.                 GServer->NPCShout ( entity, GServer->Ltbstring[iStrID]->LTBstring, GServer->GetSTLMonsterNameByID ( entity->thisnpc->refNPC ))
  18.             else                                        //Make this entity shout to the map
  19.                 GServer->NPCShout ( entity,GServer->Ltbstring[iStrID]->LTBstring,GServer->GetSTLMonsterNameByID(entity->aip_npctype))
  20.         case 2: //announce to server.
  21.             if ( entity->thisnpc->refNPC != 0)
  22.                 GServer->NPCAnnounce ( GServer->Ltbstring [ iStrID ]->LTBstring, GServer->GetSTLMonsterNameByID ( entity->thisnpc->refNPC ), entity->Position->Map)
  23.             else
  24.                 GServer->NPCAnnounce(GServer->Ltbstring[iStrID]->LTBstring, GServer->GetSTLMonsterNameByID(entity->aip_npctype), entity->Position->Map)
  25.     return AI_SUCCESS


Pretty straight forward although you might have to figure out how to make option 0 work properly since basic osrose code doesn't allow for NPCSpeak.
Not to worry though, there's not a single case of any AIP file ever using it except for file _DE_ZS.AIP which is just a test file and is not used in any real life situations
Need to lookup information on NARose items, skills, quests?
Now featuring a newly completed skill tree for all classes
Formatting fixed for different resolutions
Image

"A Gazelle is nothing but a giraffe plotted logarithmicaly"
User avatar
PurpleYouko
Rose Guru
Rose Guru
 
Posts: 4733
Joined: Fri Aug 10, 2007 2:05 pm

Re: AIP Actions

Postby PurpleYouko on Tue Jun 04, 2019 5:20 pm

AIP_REWD_029

  1. //Move to my owner's location
  2. AIP_REWD_029
  3.     CMap* map = GServer->MapList.Index[entity->Position->Map]       //get map
  4.     CCharacter* caller = map->GetCharInMap( entity->owner )         //get owner
  5.     if ( caller == NULL )                                           //can't find owner so return
  6.         return AI_SUCCESS
  7.     entity->thisnpc->stance = 1                                     //set run mode
  8.     entity->Position->source = caller->Position->current            //set destination
  9.     entity->MoveTo(caller->Position->current)                       //issue command to move. This function contains the 0x0797 move packet
  10.     entity->CurrentAction->Clear ( )                                //Clear all combat actions
  11.  
  12.     return AI_SUCCESS


very simple function that tells an entity to move to the position of its owner. If no owner is found the instruction is ignored.
Need to lookup information on NARose items, skills, quests?
Now featuring a newly completed skill tree for all classes
Formatting fixed for different resolutions
Image

"A Gazelle is nothing but a giraffe plotted logarithmicaly"
User avatar
PurpleYouko
Rose Guru
Rose Guru
 
Posts: 4733
Joined: Fri Aug 10, 2007 2:05 pm

Re: AIP Actions

Postby PurpleYouko on Tue Jun 04, 2019 5:32 pm

AIP_REWD_030

  1. //Do Trigger
  2. AIP_REWD_030
  3.     uint16 lenszTrigger     //Byte 0
  4.     char* szTrigger         //Byte 2
  5.  
  6.     char* tempName = reinterpret_cast<char*>(&szTrigger) - 2    //need to make the char array smaller since it always reads too many bytes of data
  7.     dword hash = MakeStrHash(tempName)                          //make a hash of the name so we can use it to call a trigger in QSD
  8.                                                                 //first we need to make a dummy player from this monster as only player objects can run QSD commands
  9.     CClientSocket* thisclient = new CClientSocket
  10.     CPlayer* player = new CPlayer(thisclient)
  11.     if (player == NULL)                                         //failed so return
  12.         return AI_SUCCESS
  13.     thisclient->player = (void*)player                          //run a dummy player creation script to populate all the necessary variables from the constructor
  14.     player->Position = entity->Position                         //set the position of our dummy player equal to the entitys position
  15.     QuestResult quest = player->ExecuteQuestTrigger(hash)       //Run the quest trigger
  16.     delete player                                               //clean up our memory to prevent leaks
  17.     delete thisclient
  18.     return AI_SUCCESS


This is some extremely ugly code IMO
I'm not really great at writing this kind of stuff where I have to make dummy structures and reinterpret casts horizonatally just to convert our entity (CMonster) into a dummy player (CPlayer)
It's only possible because both CMonster and CPlayer inherit from a common class CCharacter
Unfortunately AIP runs under the CMonster class while QSD runs under CPlayer so we are forced to create a dummy in order to be able to run a quest trigger from AIP.
It's horrible and ugly but it does get the job done
Need to lookup information on NARose items, skills, quests?
Now featuring a newly completed skill tree for all classes
Formatting fixed for different resolutions
Image

"A Gazelle is nothing but a giraffe plotted logarithmicaly"
User avatar
PurpleYouko
Rose Guru
Rose Guru
 
Posts: 4733
Joined: Fri Aug 10, 2007 2:05 pm

PreviousNext

Return to Tools and File Format

Who is online

Users browsing this forum: No registered users and 19 guests

cron