Skip to content

Commit

Permalink
Added new script_command for 'timed bonus/script' idea: http://rathen…
Browse files Browse the repository at this point in the history
…a.org/board/topic/72463-suggest-to-add-a-script-command-run-item-script-inside-npc-script/

-- bonus_script "<script code>",<duration>{,<flag>{,<type>{,<char_id>}}};
-- see 'doc/script_commands.txt' for more details.
-- Thank everyone who discussed it

Signed-off-by: Cahyadi Ramadhan Togihon <house.bad@gmail.com>
  • Loading branch information
cydh committed Nov 9, 2013
1 parent 9744ba4 commit 99098c1
Show file tree
Hide file tree
Showing 9 changed files with 280 additions and 33 deletions.
24 changes: 24 additions & 0 deletions doc/script_commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5059,6 +5059,30 @@ autobonus and autobonus3).

---------------------------------------

*bonus_script "<script code>",<duration>{,<flag>{,<type>{,<char_id>}}};

This command attachs script to player within specified 'duration' in second.

flag:
&1: Remove when dead
&2: Removable by dispell
&4: Removable by clearance
[TODO] &8: Save script when player logout and continue when player login back

type:
0 = Buff
1 = Debuff

NOTE:
- Cannot stack same bonus
- Max. bonus_script for a player is 10 (pc.h MAX_PC_BONUS_SCRIPT)

Example:
- Apple gives you +5 Str bonus for 1 minute when it's consumed.
512,Apple,Apple,0,15,,20,,,,,0xFFFFFFFF,63,2,,,,,,{ bonus_script "{ bonus bStr,5; }",60; },{},{}

---------------------------------------

*skill <skill id>,<level>{,<flag>};
*skill "<skill name>",<level>{,<flag>};
*addtoskill <skill id>,<level>{,<flag>};
Expand Down
2 changes: 2 additions & 0 deletions src/map/clif.c
Original file line number Diff line number Diff line change
Expand Up @@ -9877,6 +9877,7 @@ void clif_parse_QuitGame(int fd, struct map_session_data *sd)
{
set_eof(fd);
pc_damage_log_clear(sd,0);
pc_bonus_script_clear(sd);
clif_disconnect_ack(sd, 0);
} else {
clif_disconnect_ack(sd, 1);
Expand Down Expand Up @@ -10247,6 +10248,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd)
(!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout) )
{ //Send to char-server for character selection.
pc_damage_log_clear(sd,0);
pc_bonus_script_clear(sd);
chrif_charselectreq(sd, session[fd]->client_addr);
} else {
clif_disconnect_ack(sd, 1);
Expand Down
2 changes: 1 addition & 1 deletion src/map/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -1716,7 +1716,7 @@ int map_quit(struct map_session_data *sd) {
elemental_clean_effect(sd->ed);
unit_remove_map(&sd->ed->bl,CLR_RESPAWN);
}

unit_remove_map_pc(sd,CLR_RESPAWN);

if( map[sd->bl.m].instance_id ) { // Avoid map conflicts and warnings on next login
Expand Down
148 changes: 127 additions & 21 deletions src/map/pc.c
Original file line number Diff line number Diff line change
Expand Up @@ -6920,6 +6920,9 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
item_tmp.card[3]=GetWord(sd->status.char_id,1);
map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
}

//Remove bonus_script when dead
pc_bonus_script_check(sd,BSF_REM_ON_DEAD);

// changed penalty options, added death by player if pk_mode [Valaris]
if(battle_config.death_penalty_type
Expand Down Expand Up @@ -7044,7 +7047,6 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
}
}


//Reset "can log out" tick.
if( battle_config.prevent_logout )
sd->canlog_tick = gettick() - battle_config.prevent_logout;
Expand Down Expand Up @@ -10224,65 +10226,79 @@ void pc_itemcd_do(struct map_session_data *sd, bool load) {
return;
}

/**
* Clear the dmglog data from player
* @param sd
* @param md
**/
void pc_clear_log_damage_sub(int char_id, struct mob_data *md)
{
int i;
uint8 i;
ARR_FIND(0,DAMAGELOG_SIZE,i,md->dmglog[i].id == char_id);
if( i < DAMAGELOG_SIZE )
{
if (i < DAMAGELOG_SIZE) {
md->dmglog[i].id=0;
md->dmglog[i].dmg=0;
md->dmglog[i].flag=0;
}
}

/**
* Add log to player's dmglog
* @param sd
* @param id Monster's id
**/
void pc_damage_log_add(struct map_session_data *sd, int id)
{
int i = 0;
uint8 i = 0;

if( !sd )
if (!sd)
return;

for(i = 0; i < DAMAGELOG_SIZE_PC && sd->dmglog[i].id != id; i++)
if( !sd->dmglog[i].id )
{
for (i = 0; i < DAMAGELOG_SIZE_PC && sd->dmglog[i].id != id; i++)
if (!sd->dmglog[i].id) {
sd->dmglog[i].id = id;
break;
}
return;
}

/**
* Clear dmglog data from player
* @param sd
* @param id Monster's id
**/
void pc_damage_log_clear(struct map_session_data *sd, int id)
{
int i;
uint8 i;
struct mob_data *md = NULL;
if( !sd )
if (!sd)
return;

if( !id )
{
for(i = 0; i < DAMAGELOG_SIZE_PC; i++) // track every id
{
if (!id) {
for (i = 0; i < DAMAGELOG_SIZE_PC; i++) {
if( !sd->dmglog[i].id ) //skip the empty value
continue;

if( (md = map_id2md(sd->dmglog[i].id)) )
if ((md = map_id2md(sd->dmglog[i].id)))
pc_clear_log_damage_sub(sd->status.char_id,md);
}
memset(sd->dmglog,0,sizeof(sd->dmglog)); // clear all
}
else
{
if( (md = map_id2md(id)) )
else {
if ((md = map_id2md(id)))
pc_clear_log_damage_sub(sd->status.char_id,md);

ARR_FIND(0,DAMAGELOG_SIZE_PC,i,sd->dmglog[i].id == id); // find the id position
if( i < DAMAGELOG_SIZE_PC )
if (i < DAMAGELOG_SIZE_PC)
sd->dmglog[i].id = 0;
}
}


/**
* Deposit some money to bank
* @param sd
* @param money Amount of money to deposit
**/
enum e_BANKING_DEPOSIT_ACK pc_bank_deposit(struct map_session_data *sd, int money) {
unsigned int limit_check = money+sd->status.bank_vault;

Expand All @@ -10301,6 +10317,11 @@ enum e_BANKING_DEPOSIT_ACK pc_bank_deposit(struct map_session_data *sd, int mone
return BDA_SUCCESS;
}

/**
* Withdraw money from bank
* @param sd
* @param money Amount of money that will be withdrawn
**/
enum e_BANKING_WITHDRAW_ACK pc_bank_withdraw(struct map_session_data *sd, int money) {
unsigned int limit_check = money+sd->status.zeny;

Expand All @@ -10323,6 +10344,10 @@ enum e_BANKING_WITHDRAW_ACK pc_bank_withdraw(struct map_session_data *sd, int mo
return BWA_SUCCESS;
}

/**
* Clear Cirmson Marker data from caster
* @param sd
**/
void pc_crimson_marker_clear(struct map_session_data *sd) {
uint8 i;

Expand All @@ -10336,6 +10361,10 @@ void pc_crimson_marker_clear(struct map_session_data *sd) {
}
}

/**
* Show version to player
* @param sd
**/
void pc_show_version(struct map_session_data *sd) {
const char* svn = get_svn_revision();
const char* git = get_git_hash();
Expand All @@ -10350,6 +10379,83 @@ void pc_show_version(struct map_session_data *sd) {
clif_displaymessage(sd->fd,buf);
}

/** [Cydh]
* Timer for bonus_script
* @param tid
* @param tick
* @param id
* @param data
**/
int pc_bonus_script_timer(int tid, unsigned int tick, int id, intptr_t data) {
uint8 i = (uint8)data;
struct map_session_data *sd;

sd = map_id2sd(id);
if (!sd) {
ShowDebug("pc_bonus_script_timer: Null pointer id: %d data: %d\n",id,data);
return 0;
}

if (i > MAX_PC_BONUS_SCRIPT|| !(&sd->bonus_script[i]) || !sd->bonus_script[i].script) {
ShowDebug("pc_bonus_script_timer: Invalid index %d\n",i);
return 0;
}

pc_bonus_script_remove(sd,i);
status_calc_pc(sd,false);
return 0;
}

/** [Cydh]
* Remove bonus_script data from sd
* @param sd target
* @param i script index
**/
void pc_bonus_script_remove(struct map_session_data *sd, uint8 i) {
if (!sd || i < 0 || i >= MAX_PC_BONUS_SCRIPT)
return;

memset(&sd->bonus_script[i].script,0,sizeof(sd->bonus_script[i].script));
sd->bonus_script[i].script_str = NULL;
sd->bonus_script[i].tick = 0;
sd->bonus_script[i].tid = 0;
sd->bonus_script[i].flag = 0;
}

/** [Cydh]
* Clear all active timer(s) of bonus_script data from sd
* @param sd target
* @param flag reason to remove the bonus_script
**/
void pc_bonus_script_check(struct map_session_data *sd, enum e_bonus_script_flag flag) {
uint8 i, count = 0;
if (!sd)
return;

for (i = 0; i < MAX_PC_BONUS_SCRIPT; i++) {
if (&sd->bonus_script[i] && sd->bonus_script[i].script && sd->bonus_script[i].flag&flag) {
delete_timer(sd->bonus_script[i].tid,pc_bonus_script_timer);
pc_bonus_script_remove(sd,i);
count++;
}
}
if (count)
status_calc_pc(sd,false);
}

/** [Cydh]
* Clear all active timer(s) of bonus_script data from sd
* @param sd target
**/
void pc_bonus_script_clear(struct map_session_data *sd) {
uint8 i;
if (!sd)
return;
for (i = 0; i < MAX_PC_BONUS_SCRIPT; i++)
if (&sd->bonus_script[i] && sd->bonus_script[i].tid)
delete_timer(sd->bonus_script[i].tid,pc_bonus_script_timer);
}

/*==========================================
* pc Init/Terminate
*------------------------------------------*/
Expand Down
17 changes: 16 additions & 1 deletion src/map/pc.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#define MAX_PC_SKILL_REQUIRE 5
#define MAX_PC_FEELHATE 3
#define DAMAGELOG_SIZE_PC 100 // Any idea for this value?
#define MAX_PC_BONUS_SCRIPT 10

//Update this max as necessary. 55 is the value needed for Super Baby currently
//Raised to 84 since Expanded Super Novice needs it.
Expand Down Expand Up @@ -551,8 +552,17 @@ struct map_session_data {
uint8 count; //Count of target for skill like RL_D_TAIL
} c_marker;
bool flicker;
};

//Timed bonus 'bonus_script' struct [Cydh]
struct s_script {
struct script_code *script;
const char *script_str; //Used for comparing and storing on table
uint32 tick;
uint8 flag;
bool isBuff; //Can be used for deciding which bonus that buff or debuff
int tid;
} bonus_script[MAX_PC_BONUS_SCRIPT];
};

enum weapon_type {
W_FIST, //Bare hands
Expand Down Expand Up @@ -1025,6 +1035,11 @@ void pc_crimson_marker_clear(struct map_session_data *sd);

void pc_show_version(struct map_session_data *sd);

int pc_bonus_script_timer(int tid, unsigned int tick, int id, intptr_t data);
void pc_bonus_script_remove(struct map_session_data *sd, uint8 i);
void pc_bonus_script_check(struct map_session_data *sd, enum e_bonus_script_flag flag);
void pc_bonus_script_clear(struct map_session_data *sd);

#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
int pc_level_penalty_mod(struct map_session_data *sd, int mob_level, uint32 mob_race, uint32 mob_mode, int type);
#endif
Expand Down
Loading

4 comments on commit 99098c1

@Angelmelody
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WoW~ TYVM :) , its really useful.

if you still accept suggestion , for my additional suggestion is status icon
So we can specify which official or custom status icon file to use
555666

@cydh
Copy link
Contributor Author

@cydh cydh commented on 99098c1 Nov 10, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually I've planned for it, maybe I can add it later with that &8 flag. :D

@Angelmelody
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Give you a thumbs up!

@cydh
Copy link
Contributor Author

@cydh cydh commented on 99098c1 Dec 27, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, it will be be05bc3
bonus_script

Please sign in to comment.