From 9e0d52a541b2733575467ae0a7650e5d7a6cfc17 Mon Sep 17 00:00:00 2001 From: zephyrus Date: Wed, 20 Aug 2008 20:56:35 +0000 Subject: - New invisible walls system (for WOE SE and Battlegrounds). - New script commands for this system "setwall" and "delwall" - Added other scripts commands "changelook" (can be used to try clothes colors, hair styles, headgears, etc without saving this on logout). - Added getmobdrops to request a list of drop and rate of an specified class. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13101 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/clif.c | 1 + src/map/map.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/map/map.h | 11 +++++ src/map/script.c | 87 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 218 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/map/clif.c b/src/map/clif.c index a87748227..a84622d54 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -7978,6 +7978,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) clif_announce(&sd->bl, output, strlen(output) + 1, 0x00CC66, 3); } + map_iwall_get(sd); // Updates Walls Info on this Map to Client sd->state.changemap = false; } diff --git a/src/map/map.c b/src/map/map.c index 36db8ebb2..fad39c9cd 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1323,7 +1323,7 @@ int map_search_freecell(struct block_list *src, int m, short *x,short *y, int rx int rx2 = 2*rx+1; int ry2 = 2*ry+1; - if (!src && (!(flag&1) || flag&2)) + if( !src && (!(flag&1) || flag&2) ) { ShowDebug("map_search_freecell: Incorrect usage! When src is NULL, flag has to be &1 and can't have &2\n"); return 0; @@ -2436,6 +2436,120 @@ void map_setgatcell(int m, int x, int y, int gat) map[m].cell[j].water = cell.water; } +/*========================================== + * Invisible Walls + *------------------------------------------*/ +static DBMap* iwall_db; + +void map_iwall_nextxy(int x, int y, int dir, int pos, int *x1, int *y1) +{ + if( dir == 0 || dir == 4 ) + *x1 = x; // Keep X + else if( dir > 0 && dir < 4 ) + *x1 = x - pos; // Going left + else + *x1 = x + pos; // Going right + + if( dir == 2 || dir == 6 ) + *y1 = y; + else if( dir > 2 && dir < 6 ) + *y1 = y - pos; + else + *y1 = y + pos; +} + +bool map_iwall_set(int m, int x, int y, int size, int dir, bool shootable, const char* wall_name) +{ + struct iwall_data *iwall; + int i, x1 = 0, y1 = 0; + + if( size < 1 || !wall_name ) + return false; + + if( (iwall = (struct iwall_data *)strdb_get(iwall_db, wall_name)) != NULL ) + return false; // Already Exists + + if( map_getcell(m, x, y, CELL_CHKNOREACH) ) + return false; // Starting cell problem + + CREATE(iwall, struct iwall_data, 1); + iwall->m = m; + iwall->x = x; + iwall->y = y; + iwall->size = size; + iwall->dir = dir; + iwall->shootable = shootable; + safestrncpy(iwall->wall_name, wall_name, sizeof(iwall->wall_name)); + + for( i = 0; i < size; i++ ) + { + map_iwall_nextxy(x, y, dir, i, &x1, &y1); + + if( map_getcell(m, x1, y1, CELL_CHKNOREACH) ) + break; // Collision + + map_setcell(m, x1, y1, CELL_WALKABLE, false); + map_setcell(m, x1, y1, CELL_SHOOTABLE, shootable); + + clif_changemapcell(0, m, x1, y1, map_getcell(m, x1, y1, CELL_GETTYPE), ALL_SAMEMAP); + } + + iwall->size = i; + + strdb_put(iwall_db, iwall->wall_name, iwall); + map[m].iwall_num++; + + return true; +} + +void map_iwall_get(struct map_session_data *sd) +{ + struct iwall_data *iwall; + DBIterator* iter; + DBKey key; + int x1, y1; + int i; + + if( map[sd->bl.m].iwall_num < 1 ) + return; + + iter = iwall_db->iterator(iwall_db); + for( iwall = (struct iwall_data *)iter->first(iter,&key); iter->exists(iter); iwall = (struct iwall_data *)iter->next(iter,&key) ) + { + if( iwall->m != sd->bl.m ) + continue; + + for( i = 0; i < iwall->size; i++ ) + { + map_iwall_nextxy(iwall->x, iwall->y, iwall->dir, i, &x1, &y1); + clif_changemapcell(sd->fd, iwall->m, x1, y1, map_getcell(iwall->m, x1, y1, CELL_GETTYPE), SELF); + } + } + iter->destroy(iter); +} + +void map_iwall_remove(const char *wall_name) +{ + struct iwall_data *iwall; + int i, x1, y1; + + if( (iwall = (struct iwall_data *)strdb_get(iwall_db, wall_name)) == NULL ) + return; // Nothing to do + + for( i = 0; i < iwall->size; i++ ) + { + map_iwall_nextxy(iwall->x, iwall->y, iwall->dir, i, &x1, &y1); + + map_setcell(iwall->m, x1, y1, CELL_SHOOTABLE, true); + map_setcell(iwall->m, x1, y1, CELL_WALKABLE, true); + + clif_changemapcell(0, iwall->m, x1, y1, map_getcell(iwall->m, x1, y1, CELL_GETTYPE), ALL_SAMEMAP); + } + + map[iwall->m].iwall_num--; + strdb_remove(iwall_db, iwall->wall_name); +} + static void* create_map_data_other_server(DBKey key, va_list args) { struct map_data_other_server *mdos; @@ -3223,6 +3337,7 @@ void do_final(void) bossid_db->destroy(bossid_db, NULL); nick_db->destroy(nick_db, nick_db_final); charid_db->destroy(charid_db, NULL); + iwall_db->destroy(iwall_db, NULL); #ifndef TXT_ONLY map_sql_close(); @@ -3396,6 +3511,9 @@ int do_init(int argc, char *argv[]) map_db = uidb_alloc(DB_OPT_BASE); nick_db = idb_alloc(DB_OPT_BASE); charid_db = idb_alloc(DB_OPT_BASE); + + iwall_db = strdb_alloc(DB_OPT_RELEASE_DATA,2*NAME_LENGTH+2+1); // [Zephyrus] Invisible Walls + #ifndef TXT_ONLY map_sql_init(); #endif /* not TXT_ONLY */ diff --git a/src/map/map.h b/src/map/map.h index c428b8922..5a7fed46e 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -387,6 +387,12 @@ struct mapcell #endif }; +struct iwall_data { + char wall_name[50]; + short m, x, y, size, dir; + bool shootable; +}; + struct map_data { char name[MAP_NAME_LENGTH]; unsigned short index; // The map index used by the mapindex* functions. @@ -398,6 +404,7 @@ struct map_data { short bxs,bys; // map dimensions (in blocks) int npc_num; int users; + int iwall_num; // Total of invisible walls in this map struct map_flag { unsigned town : 1; // [Suggestion to protect Mail System] unsigned autotrade : 1; @@ -594,6 +601,10 @@ int cleanup_sub(struct block_list *bl, va_list ap); void map_helpscreen(int flag); // [Valaris] int map_delmap(char* mapname); +bool map_iwall_set(int m, int x, int y, int size, int dir, bool shootable, const char* wall_name); +void map_iwall_get(struct map_session_data *sd); +void map_iwall_remove(const char *wall_name); + int map_addmobtolist(unsigned short m, struct spawn_data *spawn); // [Wizputer] void map_spawnmobs(int); // [Wizputer] void map_removemobs(int); // [Wizputer] diff --git a/src/map/script.c b/src/map/script.c index 7f59625fa..4353e6be3 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -4834,6 +4834,23 @@ BUILDIN_FUNC(setlook) return 0; } +BUILDIN_FUNC(changelook) +{ // As setlook but only client side + int type,val; + TBL_PC* sd; + + type=script_getnum(st,2); + val=script_getnum(st,3); + + sd = script_rid2sd(st); + if( sd == NULL ) + return 0; + + clif_changelook(&sd->bl,type,val); + + return 0; +} + /*========================================== * *------------------------------------------*/ @@ -7115,6 +7132,42 @@ BUILDIN_FUNC(monster) mob_once_spawn(sd,m,x,y,str,class_,amount,event); return 0; } +/*========================================== + * Request List of Monster Drops + *------------------------------------------*/ +BUILDIN_FUNC(getmobdrops) +{ + int class_ = script_getnum(st,2); + int i, j = 0; + struct item_data *i_data; + struct mob_db *mob; + + if( !mobdb_checkid(class_) ) + { + script_pushint(st, 0); + return 0; + } + + mob = mob_db(class_); + + for( i = 0; i < MAX_MOB_DROP; i++ ) + { + if( mob->dropitem[i].nameid < 1 ) + continue; + if( (i_data = itemdb_exists(mob->dropitem[i].nameid)) == NULL ) + continue; + + mapreg_setreg(add_str("$@MobDrop_item") + (j<<24), mob->dropitem[i].nameid); + mapreg_setreg(add_str("$@MobDrop_rate") + (j<<24), mob->dropitem[i].p); + + j++; + } + + mapreg_setreg(add_str("$@MobDrop_count"), j); + script_pushint(st, 1); + + return 0; +} /*========================================== * モンスター発生 *------------------------------------------*/ @@ -9657,6 +9710,36 @@ BUILDIN_FUNC(guardian) return 0; } +/*========================================== + * Invisible Walls [Zephyrus] + *------------------------------------------*/ +BUILDIN_FUNC(setwall) +{ + const char *map, *name; + int x, y, m, size, dir; + bool shootable; + + map = script_getstr(st,2); + x = script_getnum(st,3); + y = script_getnum(st,4); + size = script_getnum(st,5); + dir = script_getnum(st,6); + shootable = script_getnum(st,7); + name = script_getstr(st,8); + + if( (m = map_mapname2mapid(map)) < 0 ) + return 0; // Invalid Map + + map_iwall_set(m, x, y, size, dir, shootable, name); + return 0; +} +BUILDIN_FUNC(delwall) +{ + const char *name = script_getstr(st,2); + map_iwall_remove(name); + + return 0; +} /// Retrieves various information about the specified guardian. /// @@ -12826,6 +12909,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF(warpparty,"siii"), // [Fredzilla] BUILDIN_DEF(warpguild,"siii"), // [Fredzilla] BUILDIN_DEF(setlook,"ii"), + BUILDIN_DEF(changelook,"ii"), // Simulates but don't Store it BUILDIN_DEF(set,"ii"), BUILDIN_DEF(setarray,"rv*"), BUILDIN_DEF(cleararray,"rvi"), @@ -12908,6 +12992,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF(itemskill,"vi"), BUILDIN_DEF(produce,"i"), BUILDIN_DEF(monster,"siisii*"), + BUILDIN_DEF(getmobdrops,"i"), BUILDIN_DEF(areamonster,"siiiisii*"), BUILDIN_DEF(killmonster,"ss?"), BUILDIN_DEF(killmonsterall,"s?"), @@ -13135,5 +13220,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF(setquestobjective, "iisi"), BUILDIN_DEF(setqueststatus, "ii"), BUILDIN_DEF(hasquest, "i"), + BUILDIN_DEF(setwall,"siiiiis"), + BUILDIN_DEF(delwall,"s"), {NULL,NULL,NULL}, }; -- cgit v1.2.3-70-g09d2