Explorar o código

- Added SC_ARMOR_RESIST, used by Undead Scroll, gives you resistance against elements and it's can be used with Resist Potions.
- SC_ARMOR_RESIST and SC_BENEDICTIO ends if you change your armor. Tested on iRO.
- If you call SC_ELEMENTALCHANGE with val3 = 1 it will use the level in val 1, and not a random value.
* Barricades:
- Fixed a bug when @reloadscript. Barricades should be destroyed too.
- Unbreakable barricades are only wall type (not shootable) According to Doddler info.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@12407 54d463be-8e91-2dee-dedb-b68131a5f0ec

zephyrus %!s(int64=17) %!d(string=hai) anos
pai
achega
fb7daea244
Modificáronse 7 ficheiros con 73 adicións e 23 borrados
  1. 1 0
      src/map/map.h
  2. 30 4
      src/map/mob.c
  3. 1 0
      src/map/mob.h
  4. 2 2
      src/map/npc.c
  5. 8 0
      src/map/pc.c
  6. 30 17
      src/map/status.c
  7. 1 0
      src/map/status.h

+ 1 - 0
src/map/map.h

@@ -1164,6 +1164,7 @@ struct mapcell
 struct barricade_data {
 	char npc_event[50];
 	short m, x, y, count, amount, dir;
+	bool killable;
 };
 
 struct map_data {

+ 30 - 4
src/map/mob.c

@@ -525,6 +525,7 @@ short mob_barricade_build(short m, short x, short y, short count, short dir, boo
 	barricade->m = m;
 	safestrncpy(barricade->npc_event, event, sizeof(barricade->npc_event));
 	barricade->amount = 0;
+	barricade->killable = killable;
 
 	ShowInfo("New Barricade: %s.\n", barricade->npc_event);
 
@@ -544,8 +545,8 @@ short mob_barricade_build(short m, short x, short y, short count, short dir, boo
 			md->barricade = barricade;
 		}
 
-		map_setgatcell(m, x1, y1, 5);
-		clif_changemapcell(0, m, x1, y1, 5, ALL_SAMEMAP);
+		map_setgatcell(m, x1, y1, (killable ? 5 : 1));
+		clif_changemapcell(0, m, x1, y1, (killable ? 5 : 1), ALL_SAMEMAP);
 	}
 
 	barricade->count = i;
@@ -557,7 +558,7 @@ short mob_barricade_build(short m, short x, short y, short count, short dir, boo
 }
 
 void mob_barricade_get(struct map_session_data *sd)
-{
+{ // Update Barricade cell in client - Required only on changemap
 	struct barricade_data *barricade;
 	DBIterator* iter;
 	DBKey key;
@@ -577,7 +578,7 @@ void mob_barricade_get(struct map_session_data *sd)
 		{
 			x1 = barricade->dir ? barricade->x + i : barricade->x;
 			y1 = barricade->dir ? barricade->y : barricade->y + i;
-			clif_changemapcell(sd->fd, barricade->m, x1, y1, 5, SELF);
+			clif_changemapcell(sd->fd, barricade->m, x1, y1, (barricade->killable ? 5 : 1), SELF);
 		}
 	}
 	iter->destroy(iter);
@@ -631,6 +632,31 @@ void mob_barricade_destroy(short m, const char *event)
 	map_foreachinmap(mob_barricade_destroy_sub, m, BL_MOB, event, 0);
 }
 
+void mod_barricade_clearall(void)
+{
+	struct barricade_data *barricade;
+	DBIterator* iter;
+	DBKey key;
+	short x1, y1;
+	int i;
+
+	iter = barricade_db->iterator(barricade_db);
+	for( barricade = iter->first(iter,&key); iter->exists(iter); barricade = iter->next(iter,&key) )
+	{
+		for( i = 0; i < barricade->count; i++ )
+		{
+			x1 = barricade->dir ? barricade->x + i : barricade->x;
+			y1 = barricade->dir ? barricade->y : barricade->y + i;
+
+			map_setgatcell(barricade->m, x1, y1, 0);
+			clif_changemapcell(0, barricade->m, x1, y1, 0, ALL_SAMEMAP);
+		}
+	}
+	iter->destroy(iter);
+
+	barricade_db->clear(barricade_db, NULL);
+}
+
 /*==========================================
  * Set a Guardian's guild data [Skotlex]
  *------------------------------------------*/

+ 1 - 0
src/map/mob.h

@@ -161,6 +161,7 @@ bool mob_ksprotected (struct block_list *src, struct block_list *target);
 short mob_barricade_build(short m, short x, short y, short count, short dir, bool killable, const char* event);
 void mob_barricade_destroy(short m, const char *event);
 void mob_barricade_get(struct map_session_data *sd);
+void mod_barricade_clearall(void);
 
 int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, int guardian);	// Spawning Guardians [Valaris]
 int mob_guardian_guildchange(struct block_list *bl,va_list ap); //Change Guardian's ownership. [Skotlex]

+ 2 - 2
src/map/npc.c

@@ -1679,11 +1679,10 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
 		}
 
 		if( type == SHOP && value*0.75 < id->value_sell*1.24 )
-		{// Expoit possible: you can buy and sell back with profit
+		{// Exploit possible: you can buy and sell back with profit
 			ShowWarning("npc_parse_shop: Item %s [%d] discounted buying price (%d->%d) is less than overcharged selling price (%d->%d) at file '%s', line '%d'.\n",
 				id->name, nameid, value, (int)(value*0.75), id->value_sell, (int)(id->value_sell*1.24), filepath, strline(buffer,start-buffer));
 		}
-
 		//for logs filters, atcommands and iteminfo script command
 		if( id->maxchance <= 0 )
 			id->maxchance = 10000; //10000 (100% drop chance)would show that the item's sold in NPC Shop
@@ -2845,6 +2844,7 @@ int npc_reload(void)
 	// clear npc-related data structures
 	ev_db->clear(ev_db,NULL);
 	npcname_db->clear(npcname_db,NULL);
+	mod_barricade_clearall(); // Clear Barricades
 	npc_warp = npc_shop = npc_script = 0;
 	npc_mob = npc_cache_mob = npc_delay_mob = 0;
 

+ 8 - 0
src/map/pc.c

@@ -6590,6 +6590,14 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
 		sd->weapontype1 == 0 && sd->weapontype2 == 0)
 		skill_enchant_elemental_end(&sd->bl,-1);
 
+	if(sd->status.inventory[n].equip & EQP_ARMOR) {
+		// On Armor Change...
+		if( sd->sc.data[SC_BENEDICTIO] )
+			status_change_end(&sd->bl, SC_BENEDICTIO, -1);
+		if( sd->sc.data[SC_ARMOR_RESIST] )
+			status_change_end(&sd->bl, SC_ARMOR_RESIST, -1);
+	}
+
 	sd->status.inventory[n].equip=0;
 
 	if(flag&1) {

+ 30 - 17
src/map/status.c

@@ -506,6 +506,7 @@ void initChangeTables(void)
 	StatusChangeFlagTable[SC_WATKFOOD] |= SCB_WATK;
 	StatusChangeFlagTable[SC_MATKFOOD] |= SCB_MATK;
 	StatusChangeFlagTable[SC_ARMOR_ELEMENT] |= SCB_PC;
+	StatusChangeFlagTable[SC_ARMOR_RESIST] |= SCB_PC;
 
 	if (!battle_config.display_hallucination) //Disable Hallucination.
 		StatusIconChangeTable[SC_HALLUCINATION] = SI_BLANK;
@@ -2344,6 +2345,13 @@ int status_calc_pc(struct map_session_data* sd,int first)
 			sd->subele[ELE_FIRE] += sc->data[SC_ARMOR_ELEMENT]->val3;
 			sd->subele[ELE_WIND] += sc->data[SC_ARMOR_ELEMENT]->val4;
 		}
+		if(sc->data[SC_ARMOR_RESIST])
+		{ // Undead Scroll
+			sd->subele[ELE_WATER] += sc->data[SC_ARMOR_RESIST]->val1;
+			sd->subele[ELE_EARTH] += sc->data[SC_ARMOR_RESIST]->val2;
+			sd->subele[ELE_FIRE] += sc->data[SC_ARMOR_RESIST]->val3;
+			sd->subele[ELE_WIND] += sc->data[SC_ARMOR_RESIST]->val4;
+		}
 	}
 
 	status_cpy(&sd->battle_status, status);
@@ -4981,6 +4989,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 			case SC_MATKPOTION:
 			case SC_ENCHANTARMS:
 			case SC_ARMOR_ELEMENT:
+			case SC_ARMOR_RESIST:
 				break;
 			case SC_GOSPEL:
 				 //Must not override a casting gospel char.
@@ -5094,14 +5103,16 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 			skill_enchant_elemental_end(bl,type);
 			break;
 		case SC_ELEMENTALCHANGE:
-			//Val1 is elemental change level, val2 is element to use.
-			if (!val2) //Val 3 holds the element, when not given, a random one is picked.
-				val2 = rand()%ELE_MAX;
-			//Elemental Lv is always a random value between  1 and 4.
-			if (val1 == 1)
-				val1 =1+rand()%4;
-			else if (val1 > 4)
-				val1 = 4;
+			// val1 : Element Lvl (if called by skill lvl 1, takes random value between 1 and 4)
+			// val2 : Element (When no element, random one is picked)
+			// val3 : 0 = called by skill 1 = called by script (fixed level)
+			if( !val2 ) val2 = rand()%ELE_MAX;
+
+			if( val1 == 1 && val3 == 0 )
+				val1 = 1 + rand()%4;
+			else if( val1 > 4 )
+				val1 = 4; // Max Level
+			val3 = 0; // Not need to keep this info.
 			break;
 		case SC_PROVIDENCE:
 			val2=val1*5; //Race/Ele resist
@@ -5272,10 +5283,13 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 			tick = 10000;
 			break;
 		case SC_HPREGEN:
-			if( val1 == 0 ) val1 = 1;
-
+			if( val1 == 0 ) return 0;
+			// val1 = heal percent/amout
+			// val2 = seconds between heals
+			// val4 = total of heals
+			if( val2 < 1 ) val2 = 1;
 			if( (val4 = tick/(val2 * 1000)) < 1 )
-				val4 = 1; // Number of total heals
+				val4 = 1;
 			tick = val2 * 1000; // val2 = Seconds between heals
 			break;
 		case SC_HIDING:
@@ -5892,12 +5906,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 		case SC_KAIZEL:
 			val2 = 10*val1; //% of life to be revived with
 			break;
-		case SC_ARMOR_ELEMENT: //Script generated elemental resist, verify bounds.
-			if (val1 < ELE_NEUTRAL || val1 >= ELE_MAX)
-				val1 = val2 = 0; //First Elemental resist
-			if (val3 < ELE_NEUTRAL || val3 >= ELE_MAX)
-				val3 = val4 = 0; //Second element resist
-			break;
+		// case SC_ARMOR_ELEMENT:
+		// case SC_ARMOR_RESIST:
+			// Mod your resistance against elements:
+			// val1 = water | val2 = earth | val3 = fire | val4 = wind
+			// break;
 		case SC_FASTCAST:
 			//Place here SCs that have no SCB_* data, no skill associated, no ICON
 			//associated, and yet are not wrong/unknown. [Skotlex]

+ 1 - 0
src/map/status.h

@@ -286,6 +286,7 @@ enum sc_type {
 	SC_PNEUMA,
 	SC_AUTOTRADE,
 	SC_KSPROTECTED,
+	SC_ARMOR_RESIST,
 	SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
 };
 int SkillStatusChangeTable(int skill);